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

异步函数中useState无法更新状态变量的问题排查

问题分析与解决方案

核心问题

  1. 闭包导致状态读取异常:异步循环中,choices 始终是函数初始化时的旧值,循环结束后直接访问会拿到初始空数组,这就是控制台打印undefined的原因。
  2. 对象数组去重逻辑错误:new Set(choices)无法对对象数组去重,因为对象是引用类型,每个对象的引用地址不同,Set会判定它们都是唯一值。
  3. 多次 setState 引发的异常:循环内每次匹配都调用setChoices,不仅会触发多次组件重渲染,还因状态更新的异步特性,可能导致状态合并时出现异常。

修复后的代码

const getChoices = async () => {
  try {
    setIsLoading(true);
    // 用临时数组统一收集结果,避免多次调用setState
    const newChoices = [];
    for (let i = 0; i < 1387; i++) {
      for (let j = 0; j < days.length; j++) {
        if (moment(data[i].date.start).utc().format("MM/DD/YYYY") === days[j]) {
          const kli = await Contract.methods
            .GetChoice(data[i].id)
            .call({ from: Account[0] });
          console.log(kli);
          if (kli !== "0") {
            const homeId = data[i].teams.home.id;
            const visitorId = data[i].teams.visitors.id;
            const parsedKli = parseInt(kli);
            
            if (parsedKli === homeId) {
              console.log("inserted in home");
              console.log(data[i].id, data[i].teams.home.nickname);
              newChoices.push({
                MatchID: data[i].id,
                BetTeamName: data[i].teams.home.nickname,
              });
            } else if (parsedKli === visitorId) {
              console.log("inserted in vistiroes");
              newChoices.push({
                MatchID: data[i].id,
                BetTeamName: data[i].teams.visitors.nickname,
              });
            }
          }
        }
      }
    }
    // 根据MatchID实现对象数组去重
    const uniqueChoices = Array.from(
      new Map(newChoices.map(item => [item.MatchID, item])).values()
    );
    setChoices(uniqueChoices);
    console.log(uniqueChoices); // 此处可正确打印最终结果
  } finally {
    setIsLoading(false);
  }
};

关键优化点

  • 临时数组统一收集:先将所有符合条件的条目存入newChoices,最后一次性调用setChoices,既避免了频繁重渲染,也解决了闭包无法读取最新状态的问题。
  • 正确的对象去重方式:利用Map以MatchID作为键存储条目,自动覆盖重复ID的条目,再转换为数组完成去重,适配对象数组的场景。
  • 简化条件判断逻辑:提取重复变量,让代码结构更清晰,降低出错概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 17:50:28