为什么不建议使用index作为key值?

官方回答:

在react或者vue中,循环返回链表的数据的时候,如果使用index索引值作为key会引起严重的性能问题,不推荐使用

那为什么会引起严重的性能问题呢

这就要从react和vue底层的diff算法聊起了

我们都知道react框架使用的是虚拟DOM,每次更新都会产生新的虚拟DOM,然后使用diff算法和旧的虚拟DOM进行比较,有不同才会产生新的真实DOM渲染到页面中,这样就大大的提高了效率和性能

声明

  1. key是虚拟DOM的重要标识
  2. 在页面更新的时候其起着重要的作用

具体什么作用

当前页面数据在这里插入图片描述

添加之后的页面数据在这里插入图片描述

表面上看没有啥问题

看看使用index作为key时在这个页面更新的过程中发生了什么

  1. 点击添加之后,会产生一个新的虚拟DOM树
  2. 然后这个新的DOM树与旧的进行diff
    1. diff遵循以下原则
      • 在旧的虚拟DOM中找到与新的虚拟DOM相同的key
        • 内容没有发生变化,就直接使用原来的真实DOM
        • 内容发生改变,就替换掉之前旧的虚拟DOM,生成新的真实DOM
      • 在旧的虚拟DOM中未找到与新的虚拟DOM相同的key
        • 直接生成新的真实DOM
  3. 之前"赵的key为1",现在"孙的key为1",就会进行一次内容比较
  4. 内容发现不同,就生成新的真实DOM
  5. 然后循环上面的操作

使用id作为key时在这个页面更新的过程中发生了什么

  1. 点击添加之后,会产生一个新的虚拟DOM树
  2. 然后这个新的DOM树与旧的进行diff
  3. 在旧的DOM中没有找到跟"孙对应的key",直接生成新的真实DOM
  4. 然后循环上面的操作
  5. 在旧的DOM中找到了和"赵"相同的key
  6. 发现内容也一样,直接使用之前的真实DOM

生成新的真实DOM是比较消耗性能的

上述使用index作为key只是2两条数据增加了一条,就需要生成3个新的真实DOM

如果是几百条,上千条,新增一条就需要生成N+1个新的真实DOM!!!

而使用唯一值id,新增一条就只需要生成1个新的真实DOM!!!

有些情况会产生致命的问题

我们在每个形式之后添加一个文本输入框,并输入一些文字在这里插入图片描述

然后再点击添加在这里插入图片描述

会发现使用index作为key值的时候,文本框中的内容没有对应起来!!!

为什么?

还是diff算法的原因

input框中的值变化是真实DOM发生了变化,但是虚拟DOM还是input,所以会沿用之前的DOM,这就产生了文本框和姓氏不对应的致命问题

而使用id作为key值就不会有这个问题

很多新手在做TODOlist的时候就会发现这个问题,只会知道不能使用index索引作为key值,但是真实的根本原因并没有搞清楚

什么情况下可以使用index作为索引

一般来说,只做数据的渲染就可以使用,并没有什么问题
但是涉及到数据的操作,新增删除修改的时候就不要用了

以上仅个人理解,有错误的地方望指正,一起学习,一起成长!

Logo

前往低代码交流专区

更多推荐