如何将react-dropzone与useFormState集成?

问题描述 投票:0回答:1

我正在使用react-dom库中的useFormState构建一个表单。它的字段之一涉及我用react-dropzone实现的文件输入。我当前的代码是:

表格

export default function Form() {
 const [files, setFiles] = useState<File[]>([]);

 const initialState = { message: "" };
 const [state, dispatch] = useFormState(sendForm, initialState);

  return (
    <form action={dispatch}>
      <DragDrop />
      <FormActions />
      <Button type="submit">Send</Button>
    </form>
  );
}

拖放元素(文件输入)

export default function DragDrop() {
 const onDrop = useCallback((droppedFiles: File[]) => {
   console.log(droppedFiles);
 }, []);

 const { getRootProps, getInputProps } = useDropzone({
   onDrop,
   accept: {
     "application/pdf": [".pdf"],
   },
 });

 return (
   <div {...getRootProps()}>
     <p>Drop or select a file here</p>
     <Button aria-disabled={false}>Select</Button>
     <input {...getInputProps()} name="files" />
   </div>
 );

}

形成行动

export async function postFiles(prevState: State, formData: FormData) {
 const files = formData.get("files");

 console.log("files", files);

 //implement files upload

 return {
   message: "Uploaded",
 };

}

当我提交表单并触发 postFiles 函数时,问题就出现了。当尝试从 formData 检索“file”属性并将其分配给“files”常量时,它返回空值。该常量以 null 结尾,这表明尽管在输入元素中进行了声明,但在识别表单中的 files 属性时可能存在问题。

react-dropzone 是否会覆盖“name”属性?我有什么遗漏的吗?

谢谢!

reactjs forms input react-dom react-dropzone
1个回答
0
投票

我遇到了同样的问题,这是我想出的解决方案。

React-dropzone 仅处理拖放操作,因此拖放的文件属于

DataTransfer
对象。另一方面,通过
input[type=file]
添加的文件存储在
FormData
对象中。

两者都使用FileList接口,但它们是不同的,所以你必须自己弥补差距,并将DataTransfer对象的文件添加到

input.files

为了方便起见,我创建了一个

ref
form

const formRef = useRef<HTMLFormElement>(null);

onDrop
功能中:

const onDrop = useCallback((acceptedFiles: File[], fileRejections: FileRejection[]) => {
    if (acceptedFiles.length === 1) {
        // Add the file to the input[file] element (react-dropzone doesn't do it)
        const dataTransfer = new DataTransfer();
        dataTransfer.items.add(acceptedFiles[0]);
        if (formRef.current) {
            const input: HTMLInputElement | null = formRef.current.querySelector('input[type=file]');
            if (input) {
                input.files = dataTransfer.files;
            }
        }
    // ...
    }
}

现在,拖放的文件属于表单,可以在

FormData
中访问。

希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.