react由用index作为key进行增删查改引发的问题

在这里插入图片描述
现象描述:添加小王在第一个元素,在li元素可以看出来,但是在后面的输入框小张的位置占用了。因为添加小王在第一个元素,它的key是0,旧的dom的key=0是小张。所以校长被顶上去了。看到这个现象特意去学了react虚拟dom的diff算法。

diif算法虚拟dom的更新过程:
1.旧的虚拟dom的key寻找新的dom相同的key;
2.找到相同的key,内容有变化,就更新该位置的内容
3.找到相同的key,内容没有变化,该位置的内容不变
4.若找不到,则更新真实的dom.

用index作为key,对表格进行增删查改,序号会更新排序,也就是新元素的长度多少,就会更新多少次的真实dom。这样无疑效率变低。

那么,一定用key?不用可以吗?
当不带Key的时候,采用的是遍历的方式来对比新旧节点,从而达到更新节点的效果。组件react不知道某个节点是否移动了。
当索引位置发生变化,元素的类型不同,就要重新销毁树重建,效率太地下。但是,在动态的增删中,列表渲染通常都是相同的类型,触发了列表渲染通常都是相同的类型,所以位置变动时,多半是会触发节点原地复用效果,不会导致树的销毁重建发生。只是有一点:这个节点有自己的内部状态,最经典的莫过于输入框。
在这里插入图片描述
原因是 React 做了原地复用,而 input 没有传 props,不需要打 props 补丁,保持了原样
(我原来用index作为key,也会出现这个情况,具体什么原因有待研究)

带key的时候使用的是map映射来更新节点。
在模板简单的时候使用就地复用(就是不使用key)效率会更高。没有key的情况下可以对节点就地复用,提高性能。
但是只适用于不依赖子组件状态(没有和data绑定,例如,

{{data}}

,这个是个人理解,正确性待验证)或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。
所以使用key并不意味着一定可以提高diff算法的效率。
key的作用主要是为每个节点设置一个唯一的标识,可以更快,更准确的拿到节点。
在一些情况下,还可以避免就地复用带来的副作用(表单数据错位)
表单错位的原因:
用索引作为key时,新的虚拟dom和旧的虚拟dom,key相同,组件类型也相同,就会复用组件,所以就会出现表单数据错位的现象。用id作为key,那就会重新生成一个组件,就不会出现上述问题
在这里插入图片描述

在这里插入图片描述

参考文档:https://blog.csdn.net/fe_watermelon/article/details/125550099

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值