Key 的作用
Key 是虚拟 DOM Diff 算法的 节点身份标识,用于:
- 识别节点身份:在列表更新时,通过 Key 判断哪些节点是“可复用”的,避免不必要的销毁/重建。
- 优化 Diff 性能:帮助算法快速定位节点的移动、添加、删除。
为什么不能用 Index 作为 Key?
用数组下标 index作为 Key 会在 列表顺序变化时 引发问题:
1. 性能问题
- 当列表顺序改变(如插入、删除、排序),所有节点的
index都会变化,导致 Key 全部失效。 - 示例:删除第一项后,原第二项的
index从 1 变成 0,算法会认为“Key=1 的节点消失,Key=0 的节点是新节点”,触发不必要的重建和 DOM 操作。
2. 状态错乱
-
对于有状态组件或表单元素(如输入框),复用错误的节点会导致状态残留。
-
示例:
// 初始列表 [{id: 'a', input: ''}, {id: 'b', input: '已输入内容'}] // 渲染:Key=0 → id:a,Key=1 → id:b(输入框有内容) // 删除第一项后 [{id: 'b', input: '已输入内容'}] // 渲染:Key=0 → id:b(输入框内容被清空!因为节点被当作新创建)
不加 Key 会怎样?
React 和 Vue 会默认使用 index作为 Key,导致上述问题。具体表现:
- Vue:控制台警告
"v-for requires key",性能下降且可能状态错乱。 - React:无警告,但同样用
index作为 Key,存在相同隐患。
正确做法
使用唯一且稳定的标识作为 Key:
- 数据库 ID(如
item.id) - 哈希值(如
item.hash) - 或确保不会重复的复合字段(如
user.id + timestamp)