wenshaofeng / jianshu

初学react 技术栈的项目, react相关的笔记也会写在该项目的issue
9 stars 3 forks source link

PureComponent 实践 #2

Open wenshaofeng opened 5 years ago

wenshaofeng commented 5 years ago

PureComponent

PureCompent 的作用

PureComponent会在 render 之前帮组件自动执行一次shallowEqual(浅比较),来决定是否更新组件,浅比较类似于浅复制,只会比较第一层。使用 PureComponent 相当于省去了写 shouldComponentUpdate 函数,当组件更新时,如果组件的 props 和 state:

  1. 引用和第一层数据都没发生改变, render 方法就不会触发,这是我们需要达到的效果。
  2. 虽然第一层数据没变,但引用变了,就会造成虚拟 DOM 计算的浪费。
  3. 第一层数据改变,但引用没变,会造成不渲染,所以需要很小心的操作数据。

1.数据未发生改变,render 方法不会触发; 2.数据发生改变(浅比较), render 方法会触发; 3.引用发生改变,render 方法会触发

因此,为了避免我们不小心的误操作,PureComponent 最好能和immutable.js这个库一起使用

immutable.js

Immutable.js是 Facebook 在 2014 年出的持久性数据结构的库,持久性指的是数据一旦创建,就不能再被更改,任何修改或添加删除操作都会返回一个新的 Immutable 对象。可以让我们更容易的去处理缓存、回退、数据变化检测等问题,简化开发。并且提供了大量的类似原生 JS 的方法,还有 Lazy Operation 的特性,完全的函数式编程。

ImmutableJS 最大的两个特性就是: immutable data structures(持久性数据结构)与 structural sharing(结构共享),持久性数据结构保证数据一旦创建就不能修改,使用旧数据创建新数据时,旧数据也不会改变,不会像原生 js 那样新数据的操作会影响旧数据。而结构共享是指没有改变的数据共用一个引用,这样既减少了深拷贝的性能消耗,也减少了内存。比如下图:

tree

左边是旧值,右边是新值,我需要改变左边红色节点的值,生成的新值改变了红色节点到根节点路径之间的所有节点,也就是所有青色节点的值,旧值没有任何改变,其他使用它的地方并不会受影响,而超过一大半的蓝色节点还是和旧值共享的。在 ImmutableJS 内部,构造了一种特殊的数据结构,把原生的值结合一系列的私有属性,创建成 ImmutableJS 类型,每次改变值,先会通过私有属性的辅助检测,然后改变对应的需要改变的私有属性和真实值,最后生成一个新的值,中间会有很多的优化,所以性能会很高。

总结

继承自Component的组件,若是shouldComponentUpdate返回false,就不会渲染了,继承自PureComponent的组件不用我们手动去判断prop和state,所以在PureComponent中使用shouldComponentUpdate会有如下警告:

IndexPage has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.

也是比较好理解的,就是不要在PureComponent中使用shouldComponentUpdate,因为根本没有必要

转自: React 的性能优化(一)当 PureComponent 遇上 ImmutableJS