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

React首次渲染时Map.prototype.size显示0的问题排查

问题原因

核心是异步代码的执行顺序错误:

  • 在Promise.allSettled的回调里,你用forEach遍历结果并执行带await的异步逻辑,但forEach不会等待异步函数完成,导致setResponse(newResponses)在所有JSON解析操作完成前就执行了。
  • 此时newResponses里只有初始的旧数据,异步获取的新数据还没被添加进去,所以首次渲染时response.size显示为0。
  • 后续异步操作完成后,你修改了newResponses这个Map对象,但没有再次调用setResponse触发状态更新,React不会主动重新渲染。直到其他操作(比如修改useEffect内容)触发重渲染时,才会读取到已经被修改的Map,此时size数值正确。
修复方案

把forEach替换成Promise.all,等待所有异步处理逻辑完成后再更新状态,同时修正状态不可变的问题:

Promise.allSettled(promises).then(async (results) => {
  const newResponses = new Map(response);

  // 用Promise.all等待所有异步操作完成
  await Promise.all(results.map(async (result) => {
    const url = new URL(result.value.url).pathname;

    if (result.status === 'fulfilled' && result.value.ok) {
      const data = await result.value.json();

      // 不要直接修改原状态,创建新Map后再修改
      setRequests((prev) => {
        const updatedRequests = new Map(prev);
        updatedRequests.delete(url);
        return updatedRequests;
      });

      newResponses.set(url, data);
    } else {
      setHeaderStates((prev) => ({
        ...prev,
        reload: true,
        isSaving: false,
      }));
      setFetchRequestData((prev) => ({
        ...prev,
        isErrorMessageHidden: false,
        errorMessage: 'Server request failed.',
      }));
    }
  }));

  // 所有异步操作完成后,再更新response状态
  setResponse(newResponses);
});
关键细节说明
  1. Promise.all替代forEach:results.map返回一组异步Promise,Promise.all会等待所有Promise完成,确保newResponses已经填充了所有异步获取的数据后,再调用setResponse。
  2. 状态不可变:之前直接修改setRequests的prev参数(prev.delete(url))违反了React状态不可变原则,容易导致状态更新异常,现在改为创建新的Map对象再修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:55:14