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

如何解决React结合Axios实现多文件上传进度不渲染的问题

React多文件上传进度不渲染问题解决方案

核心根因

没有遵守React的state不可变规则:你直接原地修改files数组中file对象的progress属性,React的浅比对检测不到state的引用变化,因此不会触发组件重渲染,哪怕DevTools能看到属性已经更新。
另外原代码存在语法逻辑错误:FormData的定义被写在了axios的请求配置参数内部,实际无法正常执行上传。

完整修正代码

const [files, setFiles] = useState([])
const saveDocuments = () => {
  files.forEach((file, index) => {
    // 先创建FormData,不要嵌套在请求配置里
    const formData = new FormData();
    formData.append("attached_file", file);
    formData.append("name", file.name);

    axios.post("/api/documents", formData, {
      headers: {
        "X-CSRFTOKEN": getCookie("csrftoken"),
        "Content-Type": "multipart/form-data",
      },
      onUploadProgress: (progressEvent) => {
        const percentCompleted = Math.round(
          (progressEvent.loaded * 100) / progressEvent.total
        );
        // 必须通过setFiles生成全新的state引用,触发重渲染
        setFiles(prevFiles => 
          prevFiles.map((prevFile, i) => 
            // 只更新对应索引的文件,生成新的文件对象
            i === index ? { ...prevFile, progress: percentCompleted } : prevFile
          )
        );
      },
    }).catch(err => {
      // 异步错误需要单独捕获,外层同步try/catch无效
      console.log(err);
    });
  });
};

渲染逻辑无需修改,只要state是全新引用,进度值就可以正常更新展示。

注意事项

  • 永远不要原地修改state中的对象、数组,所有state更新都必须返回新的引用,单层属性更新用浅拷贝即可
  • 目前渲染用的key是数组索引,后续如果涉及文件删除、排序操作,建议替换为文件的唯一标识(比如上传前生成的临时ID),避免渲染异常

内容的提问来源于stack exchange,提问作者Aurélien

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 21:06:03