> For the complete documentation index, see [llms.txt](https://shenjunhong.gitbook.io/blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://shenjunhong.gitbook.io/blog/yuan-ma/react/react-yuan-ma-fen-xi-zhi-key.md).

# React 中的 key 属性：原理、使用场景与注意事项

在 React 开发中，key 是一个特殊的属性，它不像普通的 props 那样供开发者直接使用，而是专为 React 内部设计的。它充当组件的身份标识，帮助 React 在渲染和更新组件时高效地工作。以下将从原理、使用场景和注意事项三个方面详细剖析 key 的作用。

## 一、key 的原理：组件身份的基石

React 的核心任务之一是高效地更新虚拟 DOM 并将其映射到真实的 DOM。为了实现这一点，React 需要一种机制来识别每个组件，尤其是在处理动态列表时。key 属性正是为此而生。

* 建立对应关系：通过为组件分配一个唯一的 key，React 能够在多次渲染之间追踪每个组件的身份。这样，React 就能判断一个组件是需要更新还是销毁并重新创建。
* 更新策略：\
  如果 key 相同，React 认为这是同一个组件。若组件的属性（props）或状态（state）发生变化，React 只更新变化的部分；若无变化，则保持不变。\
  如果 key 不同，React 认为这是一个新的组件。它会先销毁旧组件（对于类组件，会触发 componentWillUnmount），然后创建新组件（触发 constructor 和 componentDidMount）。
* 非开发者属性：需要特别指出的是，key 不是普通的 props，开发者无法在组件内部通过 this.props.key 获取它的值。它是 React 内部用来标记组件的工具。

值得一提的是，key 的存在并不是为了直接提升性能，而是为了让 React 更准确地管理组件。不过，使用得当的 key 确实能减少不必要的 DOM 操作，从而间接优化性能。

## 二、key 的使用场景

key 属性最常见的使用场景是动态生成的列表组件。例如，当使用数组的 map 方法渲染一系列子组件时，React 要求为每个子组件提供一个 key。\
示例：动态列表渲染

```jsx
const data = [
  { id: 1, name: "苹果" },
  { id: 2, name: "香蕉" },
  { id: 3, name: "橙子" },
];

function FruitList() {
  return (
    <ul>
      {data.map((item) => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}
```

在这个例子中，item.id 作为 key，确保 React 能准确识别每个

* 元素。如果列表发生增删改动，React 会根据 key 高效更新 DOM。\
  其他场景\
  除了列表，key 在其他地方也能发挥作用。例如，在条件渲染或动态组件切换时，改变 key 可以强制 React 销毁并重建组件，从而重置状态。

  ```jsx
  <Component key={someCondition ? "a" : "b"} />
  ```

  当 someCondition 变化导致 key 改变时，React 会重新创建组件实例，而不是复用已有实例。

  ### 三、key 的注意事项

  为了正确使用 key，开发者需要关注以下几点：

  1. 唯一性与稳定性

     key 的值必须在同级同类型组件中唯一，但不需要全局唯一。例如，在两个不同的

     * 列表中，key 可以重复。
     * key 必须稳定，不能使用随机值（如 Math.random()），否则每次渲染都会生成新 key，导致组件被频繁销毁和重建。
     * 正确添加位置

       key 应添加到数组生成的直接子组件上，而不是子组件内部的顶层元素。例如：

  ```jsx
  {
    data.map((item) => (
      <CustomComponent key={item.id} data={item} /> // 正确
    ));
  }
  ```

  而非：

  ```jsx
  function CustomComponent({ data }) {
    return <div key={data.id}>{data.name}</div>; // 错误
  }
  ```

  3. 避免使用索引作为 key

  使用数组索引（如 map((item, index) =>
* ）看似简单，但当列表顺序改变时，索引会失效，导致 React 无法正确追踪组件。仅在列表完全静态时才考虑使用索引。

  4. 不仅仅局限于列表

  如前所述，key 的本质是区分组件身份，因此在任何需要 React 识别组件的地方都可以使用，而不仅是数组渲染场景。

  ### 四、总结

  React 中的 key 属性是一个幕后英雄，它帮助 React 在复杂的渲染过程中保持高效和准确。虽然开发者无法直接访问 key，但通过为组件提供稳定且唯一的标识，我们可以让 React 更好地决定更新还是重建组件。

  在开发中，尤其是循环渲染组件时，添加 key 几乎成了标配。理解它的原理并遵循最佳实践，不仅能避免潜在的 bug，还能让应用运行得更流畅。记住：key 是 React 的工具，而用好它则是开发者的智慧。
