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

React多文件上传时同一state并发更新的正确处理方式?

React多文件并发上传中State并发更新的解决方案

问题背景

我正在开发一个支持多文件并发上传的React文件上传门户,结合既有代码与自研代码实现。顶层组件通过useState维护名为files的状态变量,该变量为存储各上传文件信息的对象,会被映射生成对应UI元素。单文件上传时状态更新正常,但添加第二个文件后,同一files state被多位置并发更新导致UI渲染异常。

问题根源

当前代码中更新files状态时,直接依赖了当前渲染周期的files变量(比如...files)。在并发更新场景下,多个更新操作会基于同一个旧的state快照执行,导致后执行的更新覆盖先执行的,最终丢失部分状态变更。

正确处理方式:使用函数式更新

React的useState提供了函数式更新的方式,即给状态更新函数传入一个回调函数,该回调会接收上一次的最新state作为参数,返回新的state。这样每次更新都会基于最新的状态值计算新状态,彻底避免并发更新时的状态覆盖问题。

修改后的核心代码

1. 修复updateProgress函数

const updateProgress = (uploadId, progress) => {
  // 使用函数式更新,基于最新的prevFiles计算新状态
  setFiles(prevFiles => ({
    ...prevFiles,
    [uploadId]: {
      ...prevFiles[uploadId],
      progress
    }
  }));
};

2. 修复addNewFile函数

const addNewFile = () => {
  setFiles(prevFiles => {
    const filesArray = Object.values(prevFiles);
    const lastUpload = filesArray[filesArray.length - 1];
    const newId = lastUpload.id + 1;
    return {
      ...prevFiles,
      [newId]: {
        id: newId,
        name: 'File ' + newId,
        progress: 0
      }
    };
  });
};

3. 修复UploadStatus组件的定时器逻辑

原代码中calls === 10的判断不会生效(因为setInterval是异步执行的),同时需要补全useEffect的依赖项,避免闭包捕获旧值:

const UploadStatus = ({
  file,
  updateProgress,
  uploading,
  setUploading
}) => {
  useEffect(() => {
    if (!uploading) return;

    let calls = 0;

    const interval = setInterval(() => {
      calls++;
      updateProgress(file.id, calls * 10);
      
      // 移到定时器回调内判断,达到100%时停止上传
      if (calls === 10) {
        clearInterval(interval);
        setUploading(false);
      }
    }, 1000);

    return () => clearInterval(interval);
  }, [uploading, file.id, updateProgress]); // 补全依赖项

  return (
    <div key={file.id}>
      <p>{file.name}</p>
      <progress value={file.progress} max="100" />
    </div>
  );
}

总结

函数式更新是React处理并发状态更新的标准方案,它确保每次状态更新都基于最新的state快照,不会因为闭包捕获旧state而导致更新丢失。在多个组件或异步操作同时修改同一state时,必须使用这种方式来保证状态的一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 10:55:17