寻求支持大文件量选择的React文件选择组件
React 目录选择组件(仅获取文件)
下面是完全符合你需求的组件实现,解决了Antd Upload多次触发回调、rpldy无法获取webkitRelativePath的问题:
import { useRef } from 'react'; const DirectoryFilePicker = ({ onFilesSelected }) => { const fileInputRef = useRef(null); // 打开文件选择对话框 const handleOpenPicker = () => { fileInputRef.current?.click(); }; // 处理文件选择对话框的change事件 const handleFileInputChange = (e) => { const files = Array.from(e.target.files); if (files.length > 0) { onFilesSelected(files); // 重置input,否则重复选同一目录不会触发change e.target.value = ''; } }; // 拖拽事件处理:阻止默认行为,避免浏览器跳转 const handleDragEvent = (e) => { e.preventDefault(); e.stopPropagation(); }; // 处理拖拽放下事件 const handleDrop = (e) => { handleDragEvent(e); const files = Array.from(e.dataTransfer.files); if (files.length > 0) { onFilesSelected(files); } }; return ( <div onClick={handleOpenPicker} onDragEnter={handleDragEvent} onDragOver={handleDragEvent} onDrop={handleDrop} style={{ border: '2px dashed #ccc', borderRadius: '8px', padding: '40px', textAlign: 'center', cursor: 'pointer', transition: 'border-color 0.3s', }} onMouseEnter={(e) => e.currentTarget.style.borderColor = '#1890ff'} onMouseLeave={(e) => e.currentTarget.style.borderColor = '#ccc'} > <input ref={fileInputRef} type="file" webkitdirectory directory multiple style={{ display: 'none' }} onChange={handleFileInputChange} /> <p>点击或拖拽目录到此处</p> <p style={{ fontSize: '14px', color: '#666', marginTop: '8px' }}>选择后将获取所有文件的相对路径</p> </div> ); }; export default DirectoryFilePicker;
组件使用示例
import DirectoryFilePicker from './DirectoryFilePicker'; function App() { const handleFilesReceived = (files) => { // 这里一次性拿到所有文件,仅触发一次状态更新 console.log('所有文件:', files); // 可以提取webkitRelativePath用于预览 const filePaths = files.map(file => file.webkitRelativePath); console.log('文件相对路径列表:', filePaths); }; return ( <div style={{ padding: '20px' }}> <h2>目录文件选择器</h2> <DirectoryFilePicker onFilesSelected={handleFilesReceived} /> </div> ); }
关键特性说明
- 仅允许选目录:通过原生input的
webkitdirectory和directory属性实现,浏览器会强制弹出目录选择对话框,无法选择单个文件 - 拖拽+对话框双支持:既可以点击打开选择框,也可以直接拖拽目录到组件区域
- 单次回调触发:不管选中多少文件,都会一次性将所有文件转为数组后调用
onFilesSelected,避免多次重渲染 - 保留webkitRelativePath:每个File对象都原生携带该属性,直接就能获取文件在目录中的相对路径,无需额外处理
内容的提问来源于stack exchange,提问作者Adib Baji
相关产品推荐
相关产品推荐

