React代码中对state数组内对象再次克隆的作用是什么?
movies[index] = { ...movies[index] } 代码作用说明 这行代码的核心作用是严格遵循React状态不可变更新的开发规范,避免直接修改原状态数据。
具体原理拆解:
你代码里一共做了两次拷贝,作用各有不同:
- 第一行
const movies = [...this.state.movies]只完成了数组的浅拷贝:新生成的movies数组和原this.state.movies是完全独立的引用,但数组内部存储的所有movie对象,还是和原状态里的对象共享同一个引用。 - 如果删掉疑问行,直接执行
movies[index].liked = !movies[index].liked,本质是直接修改了原状态中对应movie对象的属性,属于违规的直接修改状态操作。 - 疑问行就是针对要修改的单个
movie对象,额外做了一次浅拷贝,让新数组对应位置的元素变成全新的对象引用。后续修改liked属性时,改动只会作用在这个新生成的对象上,完全不会触动原状态里的任何数据。
为什么注释掉这行代码也能正常运行?
React的
setState本身就会触发组件重渲染,只要你传入的movies是新的数组引用,大多数普通场景下视图都会正常更新,所以你暂时看不到问题。但这种不规范的写法会留下隐性隐患:
- 当组件使用
PureComponent或者React.memo做性能优化时,因为movie对象的引用没有发生变化,组件会误判数据没有改动,跳过重渲染,导致视图不更新- 依赖状态快照的调试功能(比如时间旅行)会出现不可预期的问题
- 多状态依赖的计算逻辑可能拿到被意外修改的旧状态值,出现逻辑bug
内容的提问来源于stack exchange,提问作者buoba
相关产品推荐
相关产品推荐

