You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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);
    }
}

说明

  1. 新增isFileExists辅助函数:通过对比文件名和文件字节长度(选中文件的size对应读取后数据的byteLength)来判断文件是否重复,比单纯用文件名更准确
  2. 在循环遍历选中文件时,先调用该函数校验,已存在则直接跳过当前文件的读取和添加流程
  3. 原有克隆数组、FileReader读取、父组件回调等逻辑完全保留,仅添加去重校验步骤

内容的提问来源于stack exchange,提问作者Alisa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 19:10:19