key 为什么重要,为什么不推荐用 index?
先理解原理和示例,再练习完整口述与追问。
回答要点
key 辅助节点身份识别与复用。列表插入、删除、排序时,索引可能让不同业务数据复用同一组件实例,造成输入或选中状态错位。使用稳定、同级唯一的业务标识。
原理拆解
diff 需要把新旧兄弟节点对应起来,key 提供稳定身份。若使用 index,插入、删除、排序后同一位置的 key 仍相同,但业务记录已换了,框架可能复用原 DOM 与组件局部状态。input 的未受控内容、编辑态、焦点和校验消息就可能跟错行。key 应来自业务稳定 ID,而不是每次渲染随机生成。
示例与推演
原列表为 [A,B,C],每行内部有草稿。删除 A 后,若 key 是 0、1、2,新第 0 行 B 可能复用原 A 的实例;用 key=A.id/B.id/C.id 时,B 对应自己的旧实例。反过来,切换编辑对象时故意改变组件 key,也可以主动重建实例并重置局部状态,但要确认不会丢失需保留的数据。
易错点
key 不保证不渲染,也不是列表速度的万能开关。相同兄弟范围不能重复,随机 key 会导致反复销毁重建。
参考回答可直接练习口述
key 用来表示同级虚拟节点的业务身份,影响节点和组件实例是否复用。列表排序后,如果用下标,位置没变但业务对象变了,原实例的输入状态可能错误地跟到另一条记录。我会用稳定的业务 ID。key 不是越变化越好,稳定性和唯一性比形式重要。
面试官可能继续问追问与完整解答展开收起
追问
为什么每次随机生成 key 反而变慢?只读、固定不变的列表用 index 是否一定出错?
追问回答
每次生成随机 key 会让旧节点被删除、新节点重新创建,丢失本地状态并增加开销。完全静态、没有增删排序和有状态子节点的简单列表用下标不一定产生错误;只要记录身份可能变化,就优先用真实 ID。