症状
遇到“React 缺少 key 属性 — 列表项警告”时靠猜测只会浪费时间。请按证据排查:先复现症状,再执行针对性诊断,定位根因后修复,并用明确检查验证结果。
可观察到的症状包括:
- 控制台警告 “Each child in a list should have a unique key prop”
- 重排列表后显示的项状态错误
- 删除后输入值跳到错误的行
诊断
先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。
步骤 1
grep -rn ".map(.*=>" src/ | grep -v "key="
每个返回 JSX 的 map 都需在其返回的最外层元素上提供 key。
步骤 2
git diff src/components/List.jsx
用 item.id 而非 index 可修复重排与删除时的状态错乱。
常见诱因(按出现频率排序):
- map 回调返回元素时未提供 key
- 在列表可能重排或筛选时用数组下标作 key
- key 不唯一,如重复的 id
根因
React 借助 key 在多次渲染间匹配元素。缺少 key,或在可重排列表上用 index 作 key 时,React 无法判断哪个项移动了,因而复用了错误的 DOM 与状态。
修复
为每个渲染项提供来自数据的稳定唯一 key(id 或 slug),当列表可能改变顺序或长度时不要用数组下标。
注意:随机 key 会每次渲染都强制重挂载,破坏状态与性能;key 必须在渲染间稳定。
function TodoList({ todos }) {
return (
<ul>
{todos.map((t) => (
<li key={t.id}>{t.text}</li> // stable id, not index
))}
</ul>
);
}
// ❌ key={index} breaks state on reorder/delete
验证
重排与删除项,确认每行保持各自状态;控制台警告应消失。
修复后补充一条回归测试,复现原始症状,防止问题再次出现。
这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。