列表渲染中的 key:帮 React「认人」,不是给开发者看的注释
知识背景
列表 array.map 生成一组子元素时,React 需要判断哪些项变了、哪些可复用、哪些要卸载,以最小化 DOM 操作。key 是列表项在同层级兄弟之间的稳定身份标识。
没有 key 或 key 选得不对,会导致状态错位(输入框内容跑到别的行)、性能变差、动画异常——尤其在可排序、可增删的列表里。
知识详解与通俗解释
1. key 写在哪儿?
写在列表上下文中重复出现的那个根元素上(通常是 map 回调 return 的最外层)。
jsx
{items.map((item) => (
<li key={item.id}>{item.title}</li>
))}2. 为什么不用 index 当 key?
当列表会重排、中间插入/删除时,索引会跟着变:React 以为同一 key 对应同一组件实例,结果把 A 行的 state 复用到 B 行。
若列表静态、只读、永不重排,用 index 偶发可接受,但面试与工程规范里仍优先业务主键 id。
通俗说:key 要像身份证号,不能「排队位置变了人没变却换身份证号」。
3. key 不会传给 DOM
key 是 React 的保留提示,不会作为属性出现在真实 DOM 上;需要数据属性请另传 data-id。
4. 与 Diff 的粗浅关系
同层兄弟间,React 用 key 做重排识别;跨层级移动组件代价更大。稳定 key 让复用更准,减少整树重建。
总结
- 稳定、唯一(兄弟范围内)、可预测的 key 是列表最佳实践。
- 避免 index 作为默认可选项,尤其在可编辑表格、拖拽排序中。
- key 服务于协调算法,不等于「组件内部用来取数的主键」——后者仍应用 props 显式传递。