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

React异步更新状态后子组件未重新渲染问题排查

React状态更新后组件未重渲染的问题修复

核心问题所在

你当前的写法有两个致命问题导致组件不重渲染:

  • 直接修改原数组引用:用stateArr.push(res)修改原状态数组,React依赖状态的引用变化判断是否需要重渲染,原数组引用没改,所以setState后React认为状态没更新。
  • 异步请求顺序错误:三个fetch都是异步操作,你在请求还没返回数据时就调用了setState(stateArr),此时数组是空的;后续请求完成后修改数组也不会触发重渲染,因为引用还是原来的。

具体修复方案

方案一:用Promise.all批量处理请求(推荐)

等待所有请求完成后,基于原状态创建新数组更新状态,既保证数据完整性,又符合React状态更新规则:

useEffect(() => {
  Promise.all([
    fetch("https://catfact.ninja/fact").then(res => res.json()),
    fetch("https://catfact.ninja/fact").then(res => res.json()),
    fetch("https://catfact.ninja/fact").then(res => res.json())
  ]).then(results => {
    // 函数式更新,确保拿到最新状态
    setState(prev => [...prev, ...results]);
  });
}, []);

方案二:逐个处理请求时的正确写法

如果需要单独处理每个请求的结果,要基于当前状态创建新数组,绝对不能直接修改原数组:

fetch("https://catfact.ninja/fact")
  .then(res => res.json())
  .then(res => {
    // 用展开运算符创建新数组,传递给setState
    setState(prevState => [...prevState, res]);
  });

About组件的优化点

你组件里的rerender状态完全多余,只要父组件状态正确更新,子组件会自动重渲染。另外key={e.length}容易冲突,建议改成更唯一的标识:

const About = ({ arrayProp }) => {
  return (
    <>
      {arrayProp.map((e, idx) => (
        <div key={`fact-${e.length}-${idx}`}>
          <h6>Break</h6>
          {e.fact}
        </div>
      ))}
    </>
  );
};

为什么手动触发重渲染有效?

你加的按钮通过修改rerender让父组件重渲染,此时父组件会重新传递state给子组件——哪怕state引用没变化,父组件重渲染也会带动子组件更新,所以能看到数据,但这是临时 workaround,正确的状态更新才是解决根本问题的方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 18:36:24