Redux reducer返回新state时组件重渲染机制及React渲染优化咨询
Hi there, let's break down your questions one by one, nice and clear.
Redux Reducer返回新State时组件重渲染的具体过程
当你的Redux reducer返回一个全新的state对象(重点是新引用,而非修改原对象),Redux Store会更新内部的状态引用,接下来的流程是这样的:
- Store状态更新通知:Store检测到state引用变化后,会主动通知所有已订阅它的回调函数——这些回调一般是由
connect高阶组件或者useSelectorHook注册的。 - 状态/Props对比校验:
- 对于用
connect包裹的组件,它会调用mapStateToProps函数,把新的Store状态转换成组件所需的props;随后Redux会对mapStateToProps返回的结果和组件上一次的props做浅比较(shallow comparison),如果发现差异,就会触发组件重渲染。 - 对于使用
useSelector的组件,默认同样会做浅比较:它会把当前selector返回的值和上一次的返回值对比,若引用不同,就会触发组件的重新渲染。
- 对于用
- React组件渲染流程启动:一旦确定组件的props或内部state发生了有效变化,React就会启动渲染流程——先调用组件函数(或类组件的
render方法)生成新的虚拟DOM,接着和旧虚拟DOM做diff对比,最后把差异部分更新到真实DOM上。
简单总结:新state生成 → Store通知订阅者 → 校验组件依赖的状态/Props变化 → 触发React的重渲染流程。
React减少组件渲染次数的优化技术
这里罗列几个最常用且实用的技巧,覆盖普通React组件和Redux场景:
React.memo:这是一个高阶组件,专门用来包裹纯函数组件。它会对组件的props做浅比较,如果props没有变化,就直接跳过重渲染。注意如果props里包含复杂对象或函数,浅比较可能失效,这时候需要配合useCallback/useMemo一起使用。useCallback:用来缓存函数引用。当你把函数作为props传递给子组件时,父组件每次渲染都会重新创建新的函数引用,导致子组件不必要的重渲染。用useCallback包裹后,只有当依赖项变化时,才会生成新的函数引用,避免子组件因为函数props变化而触发渲染。useMemo:用来缓存复杂计算的结果。如果组件里有耗时的计算逻辑(比如过滤大量数据、复杂公式运算),每次渲染都会重复计算,用useMemo可以把计算结果缓存起来,只有当依赖项变化时才重新计算,既减少了计算开销,也避免了不必要的渲染。- Redux场景针对性优化:
- 给
useSelector传递自定义比较函数:比如用Redux提供的shallowEqual做浅比较,或者自己编写深比较函数,避免因为State深层对象变化但组件并不关心,而触发不必要的渲染。 - 精简
mapStateToProps:只选择组件真正需要的状态字段,不要把整个Store的State都传递给组件,减少不必要的Props变化。
- 给
- 拆分大组件:把功能复杂的大组件拆分成多个专注单一职责的小组件,让每个组件只关注自己需要的状态和Props。这样父组件渲染时,只有依赖了变化状态的子组件才会重渲染,其他子组件可以直接跳过。
- 避免在渲染阶段创建新引用:不要在组件的render函数(或函数组件的主体代码)里直接创建新对象、数组或函数,比如
const data = { name: 'test' },这样每次渲染都会生成新的引用,导致React.memo或子组件的浅比较失效。
内容的提问来源于stack exchange,提问作者Manoj landge
相关产品推荐
相关产品推荐

