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

React/React Native中更新useState对象为何两种写法效果不同

问题原因解析

核心原理:React状态的不可变性要求

React的状态设计遵循不可变性原则,要求开发者永远不能直接修改useState返回的状态值,必须创建一个全新的副本,修改副本后再传给状态更新函数。另外在开发模式的严格模式下(现在官方脚手架默认开启),React会冻结useState返回的状态对象,直接修改原状态的操作会被静默阻止或者直接抛出错误。


代码1无法生效的原因

  1. 你直接对原状态数组items执行了items[objIndex] = folder的修改操作,属于直接修改原状态的突变行为。在开发模式下items是被冻结的只读对象,这行赋值操作根本不会生效,items的内容还是原来的值。
  2. 后续你执行setItems([...items])时,展开的还是未被修改的原状态数组,最终传入setItems的内容和原状态没有差异,自然不会触发预期的更新。
    另外注意你代码里的笔误:useState('')初始值设置的是空字符串,调用数组方法findIndex会直接报错,正确的初始值应该是空数组useState([])。

代码2可以正常运行的原因

你先通过const myItems = [...items]创建了原状态数组的完全副本,这个myItems是你自主创建的普通数组,没有被React冻结,属于可写对象。后续修改myItems的元素是完全生效的,最后把修改完成的新数组传给setItems,相当于用全新的状态引用更新,符合React的状态更新规则,所以可以正常运行。


额外补充

遵循不可变性原则除了符合React的更新规则外,还有两个明显优势:

  • 避免原状态被意外修改导致的不可预期bug,保证每一次状态快照的稳定性
  • React做更新判断时只需要做浅比较(对比引用地址),不需要深度遍历对比内容,性能更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 00:36:07