Redux中两次相互抵消的状态变更为何未触发useEffect?
问题原因解析
- 你的猜测只对了一部分,这个现象是React自动批处理机制和React Redux的状态变更校验规则共同导致的,不是Redux直接对action做了合并跳过执行。
- 首先React 18及以上版本默认会把同一个同步执行上下文里的所有状态更新(包括Redux dispatch触发的更新)做批处理,你连续写的两次同步dispatch会被合并到同一个重渲染周期里处理,不会各触发一次重渲染。
- 其次React Redux的
useSelector默认会对返回的状态值做浅比较,只有返回值和上一次渲染时拿到的值不一样的时候,才会让组件重渲染。 - 放到你的场景里就很好理解了:两次dispatch执行完之后,
x最终还是等于初始的1,和上一次渲染时useSelector拿到的x值完全相等,所以React Redux认为状态没改,不需要触发组件重渲染,自然不会打印后续的日志。
你可以自己验证这个逻辑:把第二次dispatch用
setTimeout包一下延迟执行,让两次dispatch不在同一个同步执行上下文里,脱离批处理范围,这时候就会触发两次重渲染,打出你预期的3条日志。
内容的提问来源于stack exchange,提问作者Matias
相关产品推荐
相关产品推荐

