如何使用react-dropzone-uploader实现文件夹上传功能?
解决react-dropzone-uploader文件夹上传问题
你的代码无法正常工作主要有几个关键问题,以下是针对性的修正方案:
1. 修正文件夹选择属性
原代码中directory=""和webkitdirectory=""的写法错误,React中布尔属性需要传递true值而非空字符串。同时无需手动设置type="file"和multiple={true},组件会自动处理这些配置。
2. 自定义getFilesFromEvent处理文件夹文件
默认的getFilesFromEvent不会递归读取文件夹内的文件,需要自己实现递归遍历逻辑来获取所有子文件:
const getFilesFromEvent = async (event) => { const files = []; // 递归遍历文件夹结构 const traverseFileTree = async (item, path = '') => { if (item.isFile) { const file = await item.file(); // 给文件添加相对路径(可选,用于保留文件夹结构) file.relativePath = `${path}${item.name}`; files.push(file); } else if (item.isDirectory) { const directoryReader = item.createReader(); const entries = await new Promise((resolve, reject) => { directoryReader.readEntries(resolve, reject); }); for (const entry of entries) { await traverseFileTree(entry, `${path}${item.name}/`); } } }; // 处理拖拽事件 if (event.dataTransfer && event.dataTransfer.items) { for (const item of event.dataTransfer.items) { if (item.kind === 'file') { const entry = item.webkitGetAsEntry(); if (entry) { await traverseFileTree(entry); } else { files.push(item.getAsFile()); } } } } // 处理文件选择框事件 else if (event.target.files) { for (const file of event.target.files) { // 浏览器自动为文件夹内文件添加webkitRelativePath属性 file.relativePath = file.webkitRelativePath || file.name; files.push(file); } } return files; };
3. 修正selectFileInput配置
确保文件选择输入框支持文件夹选择:
const selectFileInput = ({ accept, onFiles, disabled }) => { return ( <input type="file" directory webkitdirectory multiple disabled={disabled} onChange={(e) => { getFilesFromEvent(e).then(onFiles); }} /> ); };
完整修正后的组件代码
import Dropzone from 'react-dropzone-uploader'; import 'react-dropzone-uploader/dist/styles.css'; // 预览组件示例(可自定义样式) const Preview = ({ file }) => { return ( <div style={{ padding: '8px', borderBottom: '1px solid #eee' }}> <span>{file.name}</span> <span style={{ marginLeft: '8px', color: '#666' }}> ({file.relativePath || '根目录'}) </span> </div> ); }; // 上传参数配置示例(替换为你的实际接口) const FilesMeta = () => { return { url: '/your-upload-api-endpoint' }; }; const FolderUploadDropzone = () => { return ( <Dropzone getUploadParams={FilesMeta} getFilesFromEvent={getFilesFromEvent} PreviewComponent={Preview} selectFileInput={selectFileInput} directory={true} webkitdirectory={true} inputContent={ <div> <p className="dropText">拖拽或选择文件夹</p> </div> } /> ); }; export default FolderUploadDropzone;
关键说明
- 递归遍历函数
traverseFileTree会处理拖拽的文件夹,读取所有子文件并保留相对路径信息 - 对于文件选择框触发的事件,浏览器会自动为文件夹内的文件添加
webkitRelativePath属性,可直接复用 - 若需要保留文件夹结构上传,需确保你的后端接口支持接收带相对路径的文件信息
内容的提问来源于stack exchange,提问作者Gouri Patil
相关产品推荐
相关产品推荐

