浅谈react/vue key的作用和原理,遍历不建议用索引值做key的原因

遇到过使用索引值作为key导致过数据错乱,所以梳理一下key的一些概念,

浅谈react/vue key的作用和原理:

此处需要说一下Diffing算法,简单说是,当状态中的数据发生变化时=>react/vue会根据新数据生成新的虚拟DOM=>随后进行新虚拟DOM与就虚拟DOM进行比较(找different不同点,即diffing算法),diffing算法的最小力度是标签,即进行比较的最小单位是节点/标签,并且具有多层、逐层对比,标签下的标签也参与比较,diffing规则是1、旧虚拟DOM找到了与新虚拟DOM相同的key,若虚拟DOM内容没有改变,则直接使用之前的真实DOM,若虚拟DOM内容改变,则生成新的真实DOM,随后替换掉原先的真实DOM,2、旧虚拟DOM未找到了与新虚拟DOM相同的key,则根据数据创建新的真实DOM,随后渲染到页面,综上来说,key是虚拟DOM的标识,在新旧DOM diffing时起关键作用。

遍历不建议用索引值做key的原因,先举个例子

初始数据:{id:1,num:1,data:'第一项'} {id:2,num:2,data:'第二项'}

初始DOM:<li key=0>1-第一项</li> <li key=1>2-第二项</li>

新增一条{id:3,num:3,data:'第三项'}

更新后数据:{id:1,num:1,data:'第一项'} {id:2,num:2,data:'第二项'} {id:3,num:3,data:'第三项'}

更新后DOM:<li key=0>3-第三项</li> <li key=1>1-第一项</li> <li key=2>3-第二项</li>

这样做不会引起页面出现问题,但是造成了三次将虚拟DOM=>更新真实DOM=>挂载到页面,本来可以复用2个虚拟DOM,这样做会有严重的效率问题,因为这只是三个数据,如果是1000条数据,新增一条,就相当于要进行1001次更新真实DOM的操作,但是仅限于逆序添加/删除/破坏顺序的操作,如循环后仅是展示数据是可以用索引值index来作为key值。

但是会引起严重问题的是,如果结构体内包含有输入类的DOM,例如input,select,radio等,就会产生错误的DOM更新,从而导致页面有问题,以input来说,用户在页面输入值,此时input有值,但是虚拟DOM仅是type='text‘的input,并没有value值,真实DOM是具有value值,此时添加新节点,会导致diffing后将原有的value继续保留在原DOM位置,导致数据错乱,所以此时不能用索引值作为key,所以涉及到数据增删改查时候,key可以设置为id,或为唯一标识,一般涉及数据操作,后端都会给一个id或是一个唯一标识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值