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

React Toolkit Query Dispatch异常:循环中encryptedKeys状态被覆盖

问题原因及解决方案

核心问题

  1. 闭包捕获旧状态:循环中调用的getKeys函数都捕获了同一个初始的encryptedKeys状态值(比如空数组),当异步请求完成后,所有dispatch(setEncryptedKeys([...encryptedKeys, data]))都是基于这个旧值更新,最终只会保留最后一次请求返回的密钥。
  2. 参数传递错误:getKeys函数里调用createEncryptionKey(data)时,data未定义,无法正确向API传递参数。

修复步骤

1. 使用函数式更新状态

Redux的setEncryptedKeys支持函数式更新,传入的函数会接收当前最新的状态,这样就能避免闭包带来的旧状态问题。

2. 修正参数传递

给getKeys函数添加参数,传递每个文件对应的API请求数据,确保请求能正确发送。

3. 处理异步调用(可选)

如果需要保证密钥生成完成后再更新文件列表,可以用Promise.all等待所有请求完成。

修改后的代码

DragDrop组件

function DragDrop() {
  const dispatch = useDispatch();
  const files = useSelector((state) => state.file.uplaodedFiles);
  const [createEncryptionKey] = useCreateEncryptionKeyMutation();

  // 修改getKeys,接收API请求所需的参数
  const getKeys = async (apiData) => {
    try {
      const data = await createEncryptionKey(apiData).unwrap();
      if (data) {
        // 使用函数式更新,基于最新状态添加新密钥
        dispatch(setEncryptedKeys(prevKeys => [...prevKeys, data]));
      }
    } catch (err) {
      console.log(err);
    }
  };

  const handleChange = async (file) => {
    let arr = [];
    // 收集所有异步请求
    const keyPromises = [];
    for (let i = 0; i < file.length; i++) {
      const fileItem = file[i];
      // 假设需要根据file生成API所需的key参数,这里根据实际逻辑调整
      const apiData = { key: /* 生成key的逻辑,比如基于fileItem的信息 */ };
      keyPromises.push(getKeys(apiData));
      
      const data = {
        file: fileItem,
      };
      arr.push(data);
    }
    // 可选:等待所有密钥生成完成后再更新文件列表
    await Promise.all(keyPromises);
    dispatch(setUplaodedFiles([...files, ...arr]));
  };
}

补充说明

  • 函数式更新prevKeys => [...prevKeys, data]确保每次更新都基于Redux store中的最新状态,不会因为闭包捕获旧值导致覆盖。
  • 调整getKeys的参数传递,确保API请求能拿到正确的key参数,根据你的业务逻辑补充apiData的生成规则。
  • 使用Promise.all等待所有密钥请求完成,保证文件列表更新时,对应的密钥已经存入状态(如果业务不需要强顺序,也可以去掉这一步)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:52:43