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

React render渲染的state与真实state不一致:修改数组属性后视图未同步

问题原因

  • 你在changeArr函数执行初始就深拷贝了初始状态的arr,整个循环过程中修改的都是同一个localArr对象引用,每次调用setArr传入的都是相同内存地址的对象,React做状态浅比较时会判定状态未发生变更,因此不会触发重渲染,页面内容自然不会实时更新。
  • 异步更新过程中始终基于初始的数组副本修改,没有获取最新的状态值,也会导致更新结果不符合预期。

修复代码

优化更新逻辑,每次更新时使用函数式更新获取最新状态,同时每次都生成新的数组引用触发重渲染:

import { useEffect, useState } from 'react';

const App = (p: any) => {
  console.log('render!!');
  const [arr, setArr] = useState([
    { loading: true },
    { loading: true },
    { loading: true },
    { loading: true }
  ]);

  useEffect(() => {
    changeArr();
  }, []);

  const changeArr = async () => {
    for (let i = 0; i < 4; i++) {
      await new Promise(res => setTimeout(res, 1000));
      // 函数式更新拿到最新状态,用map生成新数组,仅修改对应下标的属性
      setArr(prevArr => prevArr.map((item, index) => 
        index === i ? { ...item, loading: false } : item
      ));
    }
  };

  return (
    <>
      <div>{JSON.stringify(arr)}</div>
    </>
  );
};

export default App;

注意要点

  • 不要在异步函数执行初期就拷贝状态值,异步闭包里保存的始终是初始的状态快照,无法拿到更新后的最新状态。
  • React状态更新依赖引用变化,修改数组/对象类型的状态时必须返回全新的引用才能触发重渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 08:57:05