React之diff算法在生命周期的体现

环境&版本说明

本文中使用的版本为react 16.3.0进行构建

React生命周期

分为Mount & Update 两部分

其中Mount指的是第一次装载组件的时候触发

Update是由state或props变化后引起的组件更新。

Mount发生在何时

发生在首次渲染

无论组件处于任何一个位置,必然会有首次渲染。

发生在第二次渲染时

diff判定组件是否发生变化,如果发生变化就重新构建目标组件。

变化的判定标准有两个:

第一,依据为key

第二,依据Element的类型

具体规则

重建的过程是会将整棵组件树进行重建

如果存在多个组件,会从左往右逐个进行比较,一旦有一个组件判定为变化,则后续的所有组件都需要重建。

特别关注,如果加上key,等同于告知react,哪里组件它要进行保留(只有key和类型相同,才会避开重建组件) 如何证明?看例子!

最简单的根据类型

运行代码会发现,Input的重建会直接导致BaseInput的重建,因此,可知diff的操作是以放弃一棵子树的代价来进行更新的。这也符合视图操作的逻辑,如果你要将父节点删除,必然,子节点也必须删除。否则,你单独保留子节点是没有意义的。

从左往右遇到变化后

上诉例子,抽象层数据表示就是,分别为三次变化转折:第一次: A B第二次: A C B // 此时会销毁掉B,然后重新构建 C 和 B第三次:A B //此时会销毁C B,然后重新构建B。

引入key的情况

同样的代码,加上key以后,相当于告诉react。Input这个组件要进行保留,应该避免对他进行重建。所以,此时发生的结果如下:第一次: A B第二次: A C B // 构建一个C,添加到A 和 B之间第三次:A B // 销毁C这样的好处是,如果B组件包含了成百上千的子组件,那么如果重建那性能开销是非常巨大的,因此,通过这种方式就可以避免。注意: 如果key是一致,但是类型不一样,react是无法保留的,因为,组件都从Button变成了Input,那保留也没有意义。如果真的保留,将会让使用者产生疑惑&矛盾。如下:

总结

对diff的比较规则要理解其是以类型为判断依据,并且采用一个不匹配即抛弃所有的做法,而key(类型不变的情况下)是可以告知react进行保留;

尽量不要将视图的控制逻辑放在构造函数上,这样将会依赖于重新构建来引起组件的变化;

react不同版本上diff的处理逻辑会有差异,因此要关注版本更新说明。对未知的东西要自己手写代码进行试验。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180530G1BWB100?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

同媒体快讯

扫码关注云+社区

领取腾讯云代金券