环境&版本说明
本文中使用的版本为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的处理逻辑会有差异,因此要关注版本更新说明。对未知的东西要自己手写代码进行试验。
领取专属 10元无门槛券
私享最新 技术干货