返回

React 源码解读之 key 的作用是什么?真的能省略吗?

前端

React 的 key 是一个重要且易被忽视的属性。它在 React 的 diff 算法中扮演着至关重要的角色,用于判断两个节点是否相同,从而决定是否复用旧的 DOM 节点,减少不必要的渲染,提高渲染性能。

一、key 的概念和用途

key 是 React 为每个节点分配的一个唯一标识符,它可以是字符串、数字或布尔值。在 React 中,key 的主要用途是帮助 diff 算法判断两个节点是否相同。如果两个节点的 key 相同,则认为它们是相同的节点,React 将复用旧的 DOM 节点,而不会创建新的 DOM 节点。如果两个节点的 key 不同,则认为它们是不同的节点,React 将创建一个新的 DOM 节点。

二、key 在 diff 算法中的作用

在 React 的 diff 算法中,key 是一个非常重要的因素。它决定了 diff 算法的工作方式。如果没有 key,diff 算法将使用默认的比较方式,即比较两个节点的类型和属性。这种比较方式虽然简单,但效率不高,因为它需要逐个比较每个属性,并且无法判断两个节点是否具有相同的子节点。

当使用 key 时,diff 算法将首先比较两个节点的 key。如果 key 相同,则认为它们是相同的节点,React 将复用旧的 DOM 节点,而不会创建新的 DOM 节点。如果 key 不同,则认为它们是不同的节点,React 将创建一个新的 DOM 节点。

三、何时需要省略 key

在某些情况下,我们可以省略 key。例如,当我们使用 React 的内置组件时,React 会自动为这些组件生成 key。此时,我们不需要再手动设置 key。

const MyComponent = () => {
  return <div>Hello World!</div>;
};

在上面的代码中,我们没有为 MyComponent 设置 key。但是,React 会自动为 MyComponent 生成一个 key,因此我们不需要再手动设置 key。

四、何时不能省略 key

在大多数情况下,我们都应该为 React 组件设置 key。尤其是在以下几种情况下,我们必须为 React 组件设置 key:

  • 当我们使用列表渲染时,必须为列表中的每个元素设置 key。
  • 当我们使用 map 函数渲染时,必须为 map 函数中的每个元素设置 key。
  • 当我们使用循环渲染时,必须为循环中的每个元素设置 key。
const MyList = () => {
  const items = [1, 2, 3];
  return (
    <ul>
      {items.map((item) => {
        return <li key={item}>{item}</li>;
      })}
    </ul>
  );
};

在上面的代码中,我们为 MyList 中的每个元素设置了 key。这样,当我们更新列表中的元素时,React 就可以正确地识别哪些元素发生了变化,并只更新发生变化的元素,从而提高渲染性能。

五、key 的最佳实践

在使用 key 时,我们应该遵循以下最佳实践:

  • 尽量使用唯一的 key。
  • 避免使用循环索引作为 key。
  • 使用字符串或数字作为 key。
  • 不要使用布尔值作为 key。

总结

key 是 React 中一个非常重要的属性。它可以帮助 diff 算法判断两个节点是否相同,从而决定是否复用旧的 DOM 节点,减少不必要的渲染,提高渲染性能。在大多数情况下,我们都应该为 React 组件设置 key。尤其是在使用列表渲染、map 函数渲染和循环渲染时,我们必须为 React 组件设置 key。