【发布时间】:2020-09-20 17:54:22
【问题描述】:
我想使用 React dnd 创建一个文件上传功能,用户应该能够通过将文件拖放到 div 中来上传文件
【问题讨论】:
我想使用 React dnd 创建一个文件上传功能,用户应该能够通过将文件拖放到 div 中来上传文件
【问题讨论】:
你好,我建议这个解决方案 -
<div
className="file-select"
onDragOver={dragOver}
onDragEnter={dragEnter}
onDragLeave={dragLeave}
onDrop={fileDrop}
onClick={fileInputClicked}
>
<h4>Select File</h4>
<input
ref={fileInputRef}
className="file-input"
type="file"
multiple
onChange={filesSelected}
/>
</div>
也建议使用 ref:
const fileInputRef = useRef();
它只是一个骨架——你需要实现那些方法—— 考虑验证 - 支持哪些文件等。
此外,您可以实现文件预览、删除等 - 所以在这种情况下设计或至少解决方案的概念很重要
例如我使用这个功能进行多选:
const [selectedFiles, setSelectedFiles] = useState([]);
const [validFiles, setValidFiles] = useState([]);
const [unsupportedFiles, setUnsupportedFiles] = useState([]);
const filesSelected = () => {
if (fileInputRef.current.files.length) {
handleFiles(fileInputRef.current.files);
}
};
const handleFiles = (files) => {
for (let i = 0; i < files.length; i++) {
if (validateFile(files[i])) {
setSelectedFiles((prevArray) => [...prevArray, files[i]]);
} else {
files[i].invalid = true;
setSelectedFiles((prevArray) => [...prevArray, files[i]]);
setErrorMessage('File type not permitted');
setUnsupportedFiles((prevArray) => [...prevArray, files[i]]);
}
}
handleFileData(files);
};
【讨论】:
您可以为此使用 react dropzone 包。
npm install --save react-dropzone
或:
yarn add react-dropzone
使用钩子的示例 sn-p
import React, {useCallback} from 'react'
import {useDropzone} from 'react-dropzone'
function MyDropzone() {
const onDrop = useCallback(acceptedFiles => {
// Do something with the files
}, [])
const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop})
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
{
isDragActive ?
<p>Drop the files here ...</p> :
<p>Drag 'n' drop some files here, or click to select files</p>
}
</div>
)
}
使用包装组件的示例 sn-p
import React from 'react'
import Dropzone from 'react-dropzone'
<Dropzone onDrop={acceptedFiles => console.log(acceptedFiles)}>
{({getRootProps, getInputProps}) => (
<section>
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
</section>
)}
</Dropzone>
使用 onDrop 的回调可以得到包含文件的接受文件数组。您还可以限制大小,允许多个或仅一个和您想要接受的文件类型。
下面是一个示例片段,允许多张图片大小为 10MB,并且只允许扩展 png、jpg、jpeg。
<Dropzone
multiple={true}
minSize={0}
maxSize={10485760}
accept="image/png,image/jpg,image/jpeg"
onDrop={acceptedFiles => console.log(acceptedFiles)}>
{({getRootProps, getInputProps}) => (
<section>
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
</section>
)}
</Dropzone>
【讨论】:
查看react-uploady - upload-drop-zone
您可以从很少的代码开始,如下所示:
import Uploady from "@rpldy/uploady";
import UploadDropZone from "@rpldy/upload-drop-zone";
const App = () => (
<Uploady destination={{url: "https://my-server.com/upload"}}>
<UploadDropZone onDragOverClassName="drag-over">
<span>Drag&Drop File(s) Here</span>
</UploadDropZone>
</Uploady>);
【讨论】: