React中哪里用到了diff算法
每次React中调用了render函数,就会形成一棵由React元素构成的树。在对state以及prop进行更新时,会形成一棵新的React树。React会比较新的树和旧的树,来判定如何高效进行UI更新。这一个比较的过程就用到了diff算法。
Diff算法执行过程
React 中的diff算法,首先会比较两棵树的根节点
-
如果节点类型不同,则会卸载前一棵树并且挂载新的树。
例如:从<a>变成<div>。卸载树的时候,对应的
DOM节点也会被销毁。组件实例会执行componentWillUnmount()方法。当建立一颗新的树时,对应DOM节点会被创建以及插入DOM中。组件实例将执行UNSAFE_componentWillMount()方法,紧接着componentDidMount()方法。所有与之前的树相关联的state也会被销毁。
-
如果节点类型相同,
React会只更新有改变的属性部分。例如
// 改变前 <div className="before"></div> // 改变后 <div className="after"></div>处理完当前节点,继续对子节点进行递归操作。
-
对比同类型的组件元素
当一个组件更新时,组件实例会保持不变,因此可以在不同的渲染时保持
state一致。React将更新该组件实例的props以保证与最新的元素保持一致,并且调用该实例的UNSAFE_componentWillReceiveProps()、UNSAFE_componentWillUpdate()以及componentDidUpdate()方法。
为什么需要key
使用key是为了更高效的进行diff算法。
-
使用
key前,当输入插入非最后一项时:
<!-- 元素插入前 --> <ul> <li>second</li> <ul> <!-- 更新后 --> <ul> <li>first</li> <li>second</li> </ul>diff算法不会保留,<li>second</li>这一相同元素,而是会将所有的<li>进行更新。 -
使用
key后,React会使用key来匹配原来树上所有的子元素,增加了转换效率。
key的注意事项
-
应该具有
稳定、可预测以及列表唯一性的特质。 -
使用不稳定的
key例如Math.random(),会导致组件实例和DOM被不必要的创建,导致性能的下降。 -
最好不要用下标来定义
key,当列表有顺序的改变,会降低diff算法的速度。