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

React多文件上传时异步更新数组单个元素却覆盖全量状态问题

多文件上传进度状态覆盖问题解决方案

问题根因

该问题属于React常见的状态闭包陷阱:updateFileUploadProgress 函数在定义时会捕获当前渲染周期的selectedFiles状态值。第一个文件的上传进度触发状态更新后,组件会重新渲染生成新的updateFileUploadProgress函数,但之前已经触发的其他文件上传逻辑里,引用的还是初始渲染时绑定的旧函数,旧函数内部捕获的selectedFiles仍是初始状态值,因此每次更新都会覆盖其他文件已更新的进度。

修复方案

1. 核心修改:将状态更新改为函数式写法

修改updateFileUploadProgress,使用setState的函数式更新形式,直接从参数中获取最新的状态值,避免依赖闭包中的旧状态:

const updateFileUploadProgress = (fileName: string, progress: number) => {
  setSelectedFiles(prevFiles => {
    const currentObjectIndex = prevFiles.findIndex((x) => x.file.name === fileName);
    // 边界处理:未找到对应文件时直接返回原状态
    if (currentObjectIndex < 0) return prevFiles;
    const newState = [...prevFiles];
    newState[currentObjectIndex] = {
      ...newState[currentObjectIndex],
      currentProgress: progress
    };
    return newState;
  });
};

2. 可选优化:上传任务异步处理优化

原sendFilesHandler中使用map遍历异步函数但未处理返回的Promise数组,存在异步逻辑隐患,可修改为如下形式:

const sendFilesHandler = async () => {
  // 如需等待所有文件上传完成后执行后续逻辑,用Promise.all包裹
  await Promise.all(selectedFiles.map(async (file) => {
    const fileType = file.file.type.split('/')[0];
    const formData = new FormData();
    formData.append(fileType, file.file);
    formData.append('filename', file.file.name);
    await uploadFile(formData, updateFileUploadProgress);
  }));
  // 此处可添加上传完成的业务逻辑,如成功提示、状态重置等
};

原理解释

setState的函数式更新入参prevFiles永远指向当前最新的状态值,不依赖当前渲染闭包中的状态,无论何时触发进度更新,都能基于最新的文件列表修改对应文件的进度,不会出现覆盖其他文件进度的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 15:06:03