如何使用Lodash cloneDeep实现文件上传的重复拦截?
实现文件上传去重的React方案
要实现文件仅可上传一次的功能,核心是在添加新文件前先校验该文件是否已经存在于已上传列表中。可以通过文件名+文件大小的组合来判断(避免同名不同文件被误判),具体修改如下:
关键修改点
- 在处理每个选中文件前,先检查已上传列表中是否存在相同的文件
- 跳过已存在的文件,只处理新文件
- 保留原有文件读取、状态更新等逻辑
修改后的完整代码
const [files, setFiles] = useState([]); const onSelectFile = (e) => { try { let fileArr = cloneDeep(files); let promises = []; // 辅助函数:判断文件是否已存在 const isFileExists = (newFile) => { return fileArr.some(item => item.name === newFile.name && item.data.byteLength === newFile.size ); }; for (let file of e.target.files) { // 先校验文件是否已存在,存在则跳过 if (isFileExists(file)) { console.log(`文件 ${file.name} 已存在,无需重复上传`); continue; } promises.push( new Promise((resolve, reject) => { const fileName = file.name const type = file.type; let reader = new FileReader(); reader.readAsArrayBuffer(file); reader.onload = function (evt) { const fileData = evt.target.result; fileArr.push({ name: fileName, type: type, data: fileData, comment: "", id: `${new Date().getTime()}_${fileName}`, canDelete: true }); if (typeof props.onFileSelected === "function") props.onFileSelected(fileArr); resolve(true); } reader.onerror = function (evt) { console.log("error reading file"); reject(false); } }) ); } Promise.all(promises).then(r => { setFiles(fileArr); }) } catch(e) { console.log(e); } }
说明
- 新增
isFileExists辅助函数:通过对比文件名和文件字节长度(选中文件的size对应读取后数据的byteLength)来判断文件是否重复,比单纯用文件名更准确 - 在循环遍历选中文件时,先调用该函数校验,已存在则直接跳过当前文件的读取和添加流程
- 原有克隆数组、FileReader读取、父组件回调等逻辑完全保留,仅添加去重校验步骤
内容的提问来源于stack exchange,提问作者Alisa
相关产品推荐
相关产品推荐

