DOM的diffing算法

目录

参考官网

我们知道,当调用 React 的 render() 方法时,会创建一棵由 React 元素组成的树 
为了更高效的更新DOM树,我们引入了 diffing算法

1.算法细节如下 

①当对比两棵树时,React 首先比较两棵树的根节点。
②若根节点为不同类型的元素(如从 <a> 变成 <img>),React 会拆卸原有的树并且建立起新的树 
③当对比两个相同类型的React 元素时,React 会保留 DOM 节点,仅更新有改变的属性
④当一个组件更新时,组件实例会保持不变,因此可以在不同的渲染时保持 state一致。React 更新该组件实例的 props 以保证与最新的元素保持一致。
⑤递归 DOM 节点的子元素时,React 会同时遍历两个子元素的列表
在子元素列表末尾新增元素时,更新开销比较小
如果将新增元素插入到表头,更新开销会比较大

为了解决上述问题,React 引入了 key 属性 

2.key属性 

key是虚拟DOM的标识
当状态中的数据发生变化的时候,React会根据新数据生成新的虚拟DOM,随后React会进行新旧虚拟DOM的Diffing比较,除了上面说的,还增加了一些规则:
①新虚拟DOM如果找到和旧虚拟DOM一样的key,若虚拟DOM内容不变,直接用之前的真实DOM,变了,就生成新的DOM,替换掉原来的
②如果没找到和旧虚拟DOM一样的key,直接根据数据创建新的真实DOM,渲染到页面上

3.用index作为key会引发问题

仅用于渲染列表进行展示,其实没有问题 
但是,如果对数据进行逆序添加、逆序删除等破坏顺序的操作,会导致没有必要的DOM更新,影响效率

//虚拟DOM的初始化
<li key=0>张三</li>
<li key=1>李四</li>
//头部插入一条数据,原来DOM的key变化了,所以还得更新,其实是没有必要的
<li key=0>王五</li>
<li key=1>张三</li>
<li key=2>李四</li>

如果结构中还包含输入类的DOM,会产生错误DOM更新,界面会出问题

//虚拟DOM的初始化
<li key=0>张三<input type="text"/></li>
<li key=1>李四<input type="text"/></li>
//由于我们进行Diff比较时,是一层一层比较的
//数据更新后,此时王五后面的输入框DOM其实还是原来张三后面的输入框DOM
//但是,如果张三后面的输入框还残留着他的相关信息,页面就会出问题
<li key=0>王五<input type="text"/></li>
<li key=1>张三<input type="text"/></li>
<li key=2>李四<input type="text"/></li>

所以,最好使用数据的唯一标识作为key,如id、学号、身份证号。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漂流の少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值