概念
DOM diff 就是对比两棵虚拟 DOM 树的算法。
当组件变化时,会得到一个新的虚拟 DOM,diff 算法对比新旧虚拟 DOM 之后,得到一个 patch,然后 React 用 patch 来更新真实 DOM。
如何对比
- 首先对比两棵树的根节点
- 如果根节点的类型改变了,比如 div 变成了 p,那么直接认为整棵树都变了,不再对比子节点。此时直接删除对应的真实 DOM 树,创建新的真实 DOM 树。
- 如果根节点的类型没变,就看看属性变了没有
- 如果没变,就保留对应的真实节点
- 如果变了,就只更新该节点的属性,不重新创建节点。
- 更新 style 时,如果多个 css 属性只有一个改变了,那么 React 只更新改变的。
- 然后同时遍历两棵树的子节点,每个节点的对比过程同上。
列表渲染中的key
- 存在的原因:为了更好地复用dom节点,即列表元素顺序变化时依然可以复用。
- 对比规则:
若旧虚拟DOM中找到了与新虚拟DOM相同的key:
①.若虚拟DOM中内容没变, 直接使用之前的真实DOM。
②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。 - 用index作为key可能会引发的问题:
(1) 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
(2) 如果结构中还包含输入类的DOM:
会产生错误DOM更新 ==> 界面有问题。
- 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。