列表渲染为什么需要key?可以用index作为key吗?

1.列表渲染为什么需要key?

虚拟DOM中key的作用:

当状态中的数据发生变化时,react会根据 [新数据] 生成 [新的虚拟DOM] ,随后react进行 [新虚拟DOM] 与 [旧虚拟DOM] 的Diffing比较;

(1)旧虚拟DOM中找到了与新虚拟DOM相同的key:

<1>若虚拟DOM中内容没变,直接使用之前的真实DOM;

<2>若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM;

(2)旧虚拟DOM中未找到与新虚拟DOM相同的key;

      根据数据创建新的真实DOM,随后渲染到到页面;

  • 提高渲染性能:key 属性能够帮助 React 更快速地识别哪些列表项需要更新,从而提高渲染性能;
  • 避免重复渲染:如果没有指定 key 属性,React 会在每次更新列表时重新渲染所有的列表项,而不仅仅是新增、删除或更改的列表项;
  • 帮助 React 识别列表项:key 属性可以帮助 React 识别每个列表项,从而使 React 能够更准确地跟踪每个列表项的状态和更新;

 2.列表渲染不提供key会怎么样?

如果不提供key,React 则会无法确定某个节点是否移动了。React 只能对比相同位置的两个节点,若它们类型相同,例如均为li元素,则需要对比 props 的不同,进行 props 的打补丁。因为列表渲染通常类型都是相同的,所以在位置变动时,大多数会触发节点原地复用效果,无需担心树的销毁重建发生,原地复用在不提供 key 的时候有时候也是能正确渲染的。

注:不使用key的缺点:原地复用会使传入的 props 发生变化,导致不能利用好 React.memo 的组件缓存能力。

3.列表渲染的 key 用数组索引会怎样?

效果与不使用 key 相同,仍是将新旧节点的相同索引位置进行对比,但是控制台不会打印警告。

4.可以用index作为key吗?

<template>
    <div v-for="(item, index) in list" :key="index" >{
   
   {item.name}}</div>
</template>
const list = [
    {
        id: 1,
        name: "无敌大铁锤"
    },
    {
        id: 2,
        name: "超级小布丁"
    },
    {
        id: 3,
        name: "海绵宝宝"
    },
    {
        id:4,
        name:"皮卡丘"
    }
];

 现在,删除“皮卡丘”是正常的,若删除“超级小布丁”,则会出现异常。

下表为删除“超级小布丁”前的数据:

id key index name
1 0 1 无敌大铁锤
2 1 1 超级小布丁
3 2 2 海绵宝宝
4 3 3 皮卡丘

下表为删除“超级小布丁”后的数据:

id key index name
1 0 0 无敌大铁锤
3 1 1 海绵宝宝
4 2 2 皮卡丘

现在,除了 “无敌大铁锤” 之外,剩下的 “海绵宝宝”、“皮卡丘”,由于被发现与相应 key 的绑定关系有变化,所以被重新渲染,则会影响性能。若现在 list 的 item 是 select 的选项,“海绵宝宝”是选中的,且“超级小布丁”被删除了,用 index 作为 key 就会变成是 “皮卡丘”选中的了,这就产生了bug。若唯一id作为key,删除 “超级小布丁”后,剩下的元素因为与 key 的关系没有发生变化,都不会被重新渲染,就会达到提升性能的目的。最会,list 的 item 作为 select 的选项,也不会出现上面所描述的bug。

补充:

用index作为key可能会产生的问题;

  • 若对数据进行:逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新——界面效果没问题,但效率低;
  • 若结构中还包含输入类的DOM:会产生错误DOM更新——界面有问题;

5.开发中如何去选择key? 

  • 尽量使用每条数据的唯一标识作为key, 例如身份证号、手机号等唯一值。
  • 若不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,

使用index作为key是没有问题的。 

猜你喜欢

转载自blog.csdn.net/weixin_57959921/article/details/129482384