Skip to main content

React Key的作用

key 的作用

用于判断元素是新创建的还是被移动的元素,从而减少不必要的 Diff

React 在渲染一个列表的时候会要求我们为列表中的每一个元素都添加一个 key,这个 key 要求在列表元素中是稳定且独一无二的,一般会使用 id 来作为 key,如果说列表的每一个元素没有 id 的时候,万不得已的情况下就使用 index 来作为 key。

key 帮助 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识。它是一个特殊的属性,它是出现不是给开发者用的(例如你为一个组件设置 key 之后不能获取组件的这个 key props),而是给 react 自己用的。

react 利用 key 来识别组件,它是一种身份标识标识。每个 key 对应一个组件,相同的 key react 认为是同一个组件,这样后续相同的 key 对应组件都不会被创建。

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map(number => (
<li key={number.toString()}>{number}</li>
));

使用 index 作为 key 的缺点

当你向列表中添加一条数据或者移除某条数据时。如果该键与之前的相同,React 会认为 DOM 元素表示的组件和以前是一样的

举个例子

我们对数组开头插入一个元素,key 对应的实例都没有销毁,而是重新更新。具体更新过程我们拿 key=0 的元素来说明,插入元素之后:

  • 组件重新 render 得到新的虚拟 dom;

  • 新老两个虚拟 dom 进行 diff,新老版的都有 key=0 的组件,react 认为同一个组件,则只可能更新组件;(但是其实这个是一个新的组件)

  • 然后比较其 children,发现内容的文本内容不同,而 input 组件并没有变化,更新其子组件文本内容;

  • 因为组件的 children 中 input 组件没有变化,其又与父组件传入的 props 没有关联,所以 input 组件不会更新,导致用户输入的值不会变化(也就是说我们插入的组件有之前 key 为 0 的组件的输入值)。

可以使用索引作为 key 值的三种情况:

  • 列表和项目是静态的(它们不是计算的,也不会改变);

  • 列表中的项目没有 id;

  • 该列表永远不会重新排序或过滤;

注意

  • 元素的 key 只有放在就近的数组上下文中才有意义

一个好的经验法则是:在 map() 方法中的元素需要设置 key 属性。

  • key 只是在兄弟节点之间必须唯一

数组元素中使用的 key 在其兄弟节点之间应该是独一无二的。然而,它们不需要是全局唯一的。当我们生成两个不同的数组时,我们可以使用相同的 key 值