我有:


const [list, setList] = useState([]);

在组件的某个地方,我想做:

list[index][someKey] = some_updated_value;

setList(list);

这有效吗?

或者,这样做更好吗:

const newList = list;

newList[index][someKey] = some_updated_value;

setList(newList);

如果这样更好,为什么?

推荐答案

这两种实现都将被视为状态Mutations ,应该避免,因为这在React中是反模式的.React使用浅层引用相等性判断作为其协调过程的一部分,即,如果状态块与上一个渲染周期的对象引用相同,则假定该值相同,并跳过重新渲染.

  • 版本1

    这只是直接改变状态对象.

      list[index][someKey] = some_updated_value; // <-- mutation!
      setList(list);
    
  • 版本2

    由于newList是对list的引用,这也会直接改变state对象.

      const newList = list; // <-- newList reference to state
      newList[index][someKey] = some_updated_value; // <-- mutation!
      setList(newList);
    

React状态更新的 idea 是应用不变的更新模式.这是创建任何状态和正在更新的嵌套状态的浅拷贝的地方.这通常还与函数状态更新结合在一起,在函数状态更新中,您将回调函数传递给更新程序函数,更新程序函数被传递给要更新的前一个状态.这有助于避免过时的状态存储模块.

例子:

setList(list => list.map((item, i) => // Array.protptype.map creates new array
  i === index
    ? {                               // new object reference for updated item
      ...item,                        // shallow copy previous item state
      [someKey]: newValue             // overwrite property being updated
    }
    : item
));

好doctor :

Reactjs相关问答推荐

为什么Next.js 14无法解析页面路由路径?

根据另一个Select中的选定值更改Select中的值

UseEffect和useSelector的奇怪问题导致无限循环

在REACT-RUTER-DOMV6中使用通用页面包装组件有问题吗?

更改滑块标记的文本 colored颜色 ./Reaction/MUI 5

Next.js Next-Auth登录函数重定向到http://localhost:3000/api/auth/error

如何在物料界面react 的多选菜单中设置最大 Select 数限制

FabricJS反序列化问题

强制 useEffect 仅运行一次

useEffect内部的RETURN语句在首次按钮点击事件中似乎无效的原因是什么?

如何根据用户在react.js中的 Select , Select 多个心形图标?

使用新数据更新时,React 不更新具有过滤功能的深层嵌套对象数组中的变量状态

如何在 JS 中绘制具有不同笔画宽度的样条线

在 reactJS 中导航时页面重新加载

如何到达类组件中的状态?

在 Spring Cloud Gateway 中运行的 React SPA 页面刷新出现白标错误

将路径数组传递给Route会引发错误

在 redux 状态更改时更新react 按钮禁用状态

在状态中存储多个选定的选项

在子路由内部导航无法正常工作 - React Router v6