use*_*003 3 forms reactjs react-hooks
大多数<input>元素使用valueprop 来设置值,因此它们可以由父元素进行外部控制。
然而,<input type='file'>从属性设置其值files,我正在努力使其正常工作。files不能直接设置为 prop,但可以通过 ref 直接在 DOM 上设置,所以我使用useEffect()以下方法来完成此操作:
import React, { useEffect, useRef } from "react";
const FileInput = (props) => {
const { value } = props;
const inputRef = useRef();
useEffect(() => {
if (value === "") {
inputRef.current.value = "";
} else {
inputRef.current.files = value;
}
}, [value]);
return <input type="file" ref={inputRef} />;
};
export default FileInput;
Run Code Online (Sandbox Code Playgroud)
我想onChange()在用户选择文件时包含一个处理程序,但该<FileList>对象与 DOM 绑定,并且在尝试使用它来设置时出现错误value:
DOMException: An attempt was made to use an object that is not, or is no longer, usable
Run Code Online (Sandbox Code Playgroud)
我一直在以“正确”的方式编写受控表单输入。有没有办法正确设置files属性和value属性?
谢谢!
首先,我们从中知道How to set a value to a file input in HTML? 问题是我们无法以编程方式设置元素value的属性<input type='file'/>。
其次,我们从这个/sf/answers/4772751091/答案中知道我们可以files通过DataTransfer设置属性。
所以该FileInput组件可以是:
import { useEffect, useRef } from 'react';
import * as React from 'react';
export type FileInputProps = {
fileList: File[];
onChange(fileList: FileList): void;
};
const FileInput = ({ fileList = [], onChange }: FileInputProps) => {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (inputRef.current) {
const dataTransfer = new DataTransfer();
fileList.forEach((file) => dataTransfer.items.add(file));
inputRef.current.files = dataTransfer.files;
}
}, [fileList]);
return (
<input
type="file"
ref={inputRef}
data-testid="uploader"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
onChange(e.target.files);
}}
/>
);
};
export default FileInput;
Run Code Online (Sandbox Code Playgroud)
有关现场演示,请参阅stackblitz