深拷贝和浅拷贝不直接决定增量渲染,而是通过影响PureComponent或shouldComponentUpdate对数据变化的识别来间接控制渲染;浅拷贝是shallowEqual的基础,仅比较第一层引用;深拷贝用于生成新引用使浅比较生效,而非在shouldComponentUpdate中执行。

深拷贝和浅拷贝本身不直接“决定”增量渲染策略,而是影响 PureComponent 或手动写的 shouldComponentUpdate 是否能正确识别数据变化,从而间接决定要不要渲染。
浅拷贝是PureComponent的默认行为基础
PureComponent 内部调用的是 shallowEqual,它只比较 props 和 state 的第一层:
- 对基本类型(string/number/boolean/null/undefined)直接用
Object.is比较值 - 对对象或数组,只检查它们是否是同一个引用(
===),不递归比内容 - 比如
{a: 1, b: {c: 2}}改了b.c,但b引用没变 → PureComponent 认为没变,跳过渲染
深拷贝不是解决方案,而是规避浅比较缺陷的手段
你不需要在 shouldComponentUpdate 里做深拷贝来“触发更新”,那反而低效。深拷贝常用于更新数据时保证引用变化,让 shallowEqual 能捕获到:
- 错误写法(引用不变,PureComponent 不更新):
this.state.list.push(item); this.setState({ list: this.state.list }); - 正确写法(生成新引用):
this.setState(prev => ({ list: [...prev.list, item] }));或用 Immutable.js / Immer - 本质不是“用深拷贝判断”,而是“用新引用让浅比较生效”
shouldComponentUpdate 中该怎么做判断
如果你没用 PureComponent,而是自己写 shouldComponentUpdate,可以按需选择比较粒度:
- 想省事且数据结构扁平 → 直接复刻 shallowEqual 逻辑(推荐)
- 关键字段少 → 只比几个确定会驱动视图的 prop/state,例如:
return nextProps.userId !== this.props.userId || nextState.count !== this.state.count; - 嵌套深但更新敏感 → 用
JSON.stringify粗略比(仅限小数据、无函数/undefined/Date)或引入 fast-deep-equal 库 - 避免在 shouldComponentUpdate 里做深拷贝或遍历大对象,这会抵消优化收益
什么时候该放弃浅比较思路
当组件依赖的数据天然深度嵌套、频繁局部变更,又无法控制父级传入方式时:
- 用 React.memo + 自定义 comparer 替代 PureComponent(函数组件更灵活)
- 改用 Immer:写法像直接修改,底层自动产生不可变引用,兼容 shallowEqual
- 拆分子组件,让 Pure/memo 控制粒度更细,而非在一个大组件里硬扛深比较


















