React ShouldComponentUpdate 与不可变值

shouldComponentUpdate(nextProps, nextState)
  1. 组件会根据 shouldComponetUpdate 的返回值,判断组件是否会重新渲染。
  2. shouldComponetUpdate 返回 true,则组件重新渲染,反之则不重新渲染。默认返回 ture,即 React 默认重新渲染。
  3. 父组件更新时,子组件会默认更新;
  4. 有了上面三条就意味着,在父组件更新的情况下,及时子组件没有任何变动,子组件都会被更新。
  5. 于是,我们就可以在子组件里面在 shouldComponentUpdate 中添加一些逻辑,来控制子组件是否每次都要重新渲染;
  6. React 的 PureComponent 帮我们做了这件事情,只不过 PureComponent 只帮我们做了浅层的比较,所以我们在设计 state 时应该尽量合理;
  7. React.memo 就是函数组件的 PureComponent;

使用 shouldComponentUpdate 应该注意的点:

  1. SCU 默认返回 true,即 React 默认重新渲染所有子组件;
  2. 必须配合“不可变值”来使用;
  3. 可以不使用 SCU,等有性能问题的时候再进行优化;不要为了用而用!!!

为什么 shouleComponentUpdat 一定要配合不可变值使用?

  1. SCU 默认返回 true,即 React 会默认重新渲染组件;
  2. 但如果说为了做性能优化,React 在 SCU 内部做了 props 的深度比较,会发生什么呢?
  3. 我们在 SCU 函数内部对新旧 props 进行深度比较(注意:这里的深度比较是指处理引用的地址之外,数据其他的值都相等);
  4. 如果比较结果相等,SCU 返回 false ,即组件不用重新渲染;
  5. 如果比较结果不相等,说明数据发生了变化,SCU 返回 true,即组件需要重新渲染;
  6. 上面的逻辑看起来没有任何问题,但是这一切是发生在开发者使用的不可变值的基础上。
  7. 而不是所有开发者都能遵守 React 的规范在 setState 时使用不可变值的。
  8. 如果有刚开始使用 React 进行开发的人,在用 setState 更新数据时直接操作了原来的数据,即改变了旧的 state 来生成新的 state
  9. 比如,对数组使用 push、pop 等方法改变了原数组,或者直接改变了对象的值;
  10. 那么 state 通过 props 传值到子组件时,旧的 props 和新的 props 会永远相等,于是 SCU 永远会返回 false ,导致子组件不会重新渲染;
  11. 而这个时候开发者不会认为是自己的错误,反而认为是 React 出现了 bug,这是 React 的设计者不愿意看到的。
  12. 所以 SCU 默认返回 true,默认子组件会重新渲染,而且预留了口子让开发者进行必要的性能优化;
  13. 所以在 React 里面一定要使用不可变值。

猜你喜欢

转载自blog.csdn.net/josavion/article/details/113250141