React项目中用react-dropzone实现图片去重及4-9张上传限制
解决react-dropzone重复上传和数量限制问题
修改思路
- 去重逻辑:直接在
onDrop中过滤已存在的文件,无需额外状态变量 - 数量限制:计算当前已上传文件数与可添加的最大数量,确保总数量不超过9;提交时校验是否达到最少4张的要求
修改后的完整代码
import { useState } from 'react'; import { useDropzone } from 'react-dropzone'; const FileUpload = () => { const [files, setFiles] = useState([]); const { getRootProps, getInputProps } = useDropzone({ accept: { "image/*": [] }, onDrop: (acceptedFiles) => { // 1. 过滤重复文件(结合文件名、大小、修改时间,避免同名不同文件被误判) const uniqueNewFiles = acceptedFiles.filter(newFile => !files.some(existingFile => existingFile.name === newFile.name && existingFile.size === newFile.size && existingFile.lastModified === newFile.lastModified ) ); // 2. 计算可添加的文件数量,确保总数量不超过9 const availableSlots = 9 - files.length; const filesToAdd = uniqueNewFiles.slice(0, availableSlots); if (filesToAdd.length === 0) return; // 3. 为新文件生成预览链接并更新状态 setFiles(prev => [ ...prev, ...filesToAdd.map(file => ({ ...file, preview: URL.createObjectURL(file) })) ]); }, }); // 提交时校验最少上传4张 const handleSubmit = () => { if (files.length < 4) { alert('请至少上传4张图片'); return; } // 这里写你的提交逻辑,比如上传到服务器等 console.log('提交的文件:', files); }; return ( <div> <div {...getRootProps({ className: 'dropzone' })}> <input {...getInputProps()} /> <p>拖拽图片到这里,或点击选择文件(最多9张,最少4张)</p> </div> <div className="file-previews"> {files.map((file, idx) => ( <div key={idx} className="preview-item"> <img src={file.preview} alt={file.name} style={{ width: '100px', height: '100px' }} /> <button onClick={() => { // 删除文件时释放预览链接,避免内存泄漏 URL.revokeObjectURL(file.preview); setFiles(prev => prev.filter((_, i) => i !== idx)); }}>删除</button> </div> ))} </div> <button onClick={handleSubmit}>提交</button> </div> ); }; export default FileUpload;
关键修改说明
去重优化:
- 移除原有的
found状态,通过filter+some直接筛选未上传过的文件 - 结合
name、size、lastModified三个字段判断文件唯一性,比单一文件名更准确
- 移除原有的
数量控制:
- 计算
availableSlots(剩余可上传数量),通过slice截取新文件数组,确保总数量不超过9 - 在提交函数中校验文件数量是否达到4张,给出提示
- 计算
内存优化:
- 删除文件时调用
URL.revokeObjectURL(file.preview)释放预览链接,避免浏览器内存泄漏
- 删除文件时调用
内容的提问来源于stack exchange,提问作者mobix
相关产品推荐
相关产品推荐

