为什么在 React 中使用索引(Index)作为 Key 是个坏主意

你在 React 中构建了一个动态列表。你删除了一个项目。突然间,另一个项目的 UI 状态发生了变化。或者,你对列表进行了排序,结果输入的数据出现在了错误的组件中。

发生这种情况是因为你使用了数组索引作为 key。

React 使用一种称为虚拟 DOM(Virtual DOM)的系统来更新你的 UI。当状态发生变化时,React 会将新树与旧树进行比较。这个过程被称为协调(reconciliation)。

key 属性就像是组件的身份证。它告诉 React:

  • 哪个项目发生了变化。
  • 哪个项目是新增的。
  • 哪个项目被删除了。

如果你使用索引作为 key,就会产生问题。数组是动态的。当你添加、删除或重新排序项目时,索引就会发生变化。

以下是失效的原因:

  1. 性能问题 如果你在列表开头插入一个项目,其后的每一个项目都会获得一个新的索引。React 会认为每个项目都发生了变化,从而重新渲染整个列表,而不是仅重新渲染新增的项目。

  2. 状态 Bug 这是最危险的部分。如果你的列表项包含内部状态(例如输入框或复选框),索引会导致 Bug。

想象一下,你在第一个任务的输入框中输入了 "Important"。然后你删除了该任务。如果你使用索引作为 key,React 会发现索引 0 仍然存在,于是它会复用旧的组件。现在,你的 "Important" 文本就会出现在第二个任务的输入框中。

正确做法:

  • 使用数据库 ID:始终使用数据库中的唯一 ID(例如 _idid)。
  • 在前端生成 ID:如果你没有数据库,可以使用 uuidnanoid 等库。
  • 使用浏览器 API:使用 window.crypto.randomUUID() 这种内置方式来创建唯一 ID。

什么时候可以安全地使用索引? 只有当你的列表满足以下三个规则时才可以:

  • 列表是静态的(不添加或删除项目)。
  • 列表从不重新排序(不进行排序或过滤)。
  • 项目没有内部状态(没有输入框或复选框)。

停止使用索引作为 key,以保持你的应用快速且无 Bug。

来源:https://dev.to/banti_kevat_8e2d123bb7994/react-me-index-as-key-kyun-bura-hai-best-practice-in-hindi-3fj4