React DOM Diffing与 Key(三)

React DOM Diffing与 Key(三)

React 官网链接:

接着上节 React 组件生命周期与三大属性state、refs、props(二)

DOM Diffing 算法

调用 setState() 方法进行组件更新的时候, 是一种合并,不是替换,这也是React高效的原因之一~,如图:

请添加图片描述

setState() 更新状态:

  • 重新创建虚拟DOM
  • 新旧节点比较
    • 若新旧节点相同,则不更新
    • 若新旧节点差异,则进行更新
  • 局部页面重绘

Key

虚拟 DOM 中 key 是虚拟DOM对象的标识,在更新显示时用 key 来判断

详细的说:当状态中的数据发生变化时,react会根据【新数据】生成【新的虚拟DOM】, 随后React进行【新虚拟DOM】与【旧虚拟DOM】的 diff比较,比较规则如下:

  • 旧虚拟DOM中找到了与新虚拟DOM相同的key
  • 若虚拟DOM中内容没变, 直接使用之前的真实DOM
  • 若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM
  • 旧虚拟DOM中未找到与新虚拟DOM相同的key:
    • 根据数据创建新的真实DOM,随后渲染到到页面

总之:在进行 DOM Diffing 比较的时候,Key 起着关键的作用

有以下这个情形:(列表数据进行DOM Diffing,利用什么作为Key?)

1、使用index索引值作为key

初始数据:
		{id:1,name:'小张',age:18},
		{id:2,name:'小李',age:19},
		
初始的虚拟DOM<li key=0>小张---18<input type="text"/></li>
		<li key=1>小李---19<input type="text"/></li>

更新后的数据:(将数据插入到第一条)
		{id:3,name:'小王',age:20},
		{id:1,name:'小张',age:18},
		{id:2,name:'小李',age:19},
		
更新数据后的虚拟DOM(index都会变了,那么key判断就三条数据都会更新)
		<li key=0>小王---20<input type="text"/></li>
		<li key=1>小张---18<input type="text"/></li>
		<li key=2>小李---19<input type="text"/></li>

那么用index作为key可能会引发的问题:

  • 若对数据进行:逆序添加、逆序删除等破坏顺序操作:

    会产生没有必要的真实DOM更新 ==> 界面效果没问题,但效率低

  • 如果结构中还包含输入类的DOM:

    会产生错误DOM更新 ==> 界面有问题

  • 注意!如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,

    仅用于渲染列表用于展示,使用index作为key是没有问题的。

2、使用数据唯一 id 作为key

初始数据:
	{id:1,name:'小张',age:18},
	{id:2,name:'小李',age:19},

初始的虚拟DOM<li key=1>小张---18<input type="text"/></li>
	<li key=2>小李---19<input type="text"/></li>

更新后的数据:
	{id:3,name:'小王',age:20},
	{id:1,name:'小张',age:18},
	{id:2,name:'小李',age:19},
        
更新数据后的虚拟DOM(key不变,那么就只会更新新数据)
	<li key=3>小王---20<input type="text"/></li>
	<li key=1>小张---18<input type="text"/></li>
	<li key=2>小李---19<input type="text"/></li>

开发中如何选择key?:

  • 最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
  • 如果确定只是简单的展示数据,用index也是可以的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值