React列表渲染时key值用index有什么问题?

UX秀丽 阅读 14

我最近在用React写一个待办事项列表,发现用index当key的时候,删除中间某一项,后面的项动画会错乱,而且输入框内容好像会串掉。是不是不能用index做key啊?

我试过改成用id,但有些临时数据还没保存到后端,没有唯一id,这时候该怎么处理?

const TodoList = ({ todos, onDelete }) => {
  return (
    <ul>
      {todos.map((todo, index) => (
        <li key={index}>
          <input defaultValue={todo.text} />
          <button onClick={() => onDelete(index)}>删除</button>
        </li>
      ))}
    </ul>
  );
};
我来解答 赞 4 收藏
二维码
手机扫码查看
2 条解答
设计师鑫钰
用index当key确实会出问题,删除中间项后后面的元素key全变了,React会错误复用DOM节点导致状态错乱。临时数据可以用nanoid生成唯一id,或者简单点用Date.now()加随机数也行,试试这个:

import { nanoid } from 'nanoid';

const TodoList = ({ todos, onDelete }) => {
return (

    {todos.map((todo) => (




  • ))}

);
};

// 创建todo时生成id
const addTodo = (text) => {
const newTodo = {
id: nanoid(), // 或者 Date.now() + Math.random()
text
};
setTodos([...todos, newTodo]);
};


已经在后端存过的数据就用后端id,纯前端临时数据生成一个就行,nanoid很轻量。
点赞 1
2026-03-02 16:03
Dev · 统乐
用 index 当 key 确实会出问题,尤其是涉及列表项顺序变化或可变状态的场景,比如你这个待办事项列表里有输入框。React 依赖 key 来识别元素的“身份”,如果 key 是 index,那删除中间一项后,后面的项的 index 就会整体前移,React 会以为是“同一个位置的元素内容变了”,而不是“删了一个,后面项没动”,于是错误地复用组件实例——这就是为什么输入框内容会串、动画会错乱。

按照规范,key 应该是稳定、唯一、可预测的标识符。如果数据还没保存到后端、没有 id,那可以考虑在前端生成一个临时唯一 id,比如用 nanoid、uuid,或者简单点用时间戳加随机数(适合临时 demo)。比如:

import { nanoid } from 'nanoid';

const initialTodos = [
{ id: nanoid(), text: '买牛奶' },
{ id: nanoid(), text: '写报告' },
{ id: nanoid(), text: '健身' },
];

// 或者如果只是临时用,也可以简单生成:
const getTempId = (() => {
let count = 0;
return () => temp-${Date.now()}-${count++};
})();


然后渲染时:

const TodoList = ({ todos, onDelete }) => {
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>
<input defaultValue={todo.text} />
<button onClick={() => onDelete(todo.id)}>删除</button>
</li>
))}
<ul>
);
};


删除时别用 index,直接传 id 过去,这样 React 才能准确追踪每个项,不会把输入框内容“张冠李戴”。

要是数据量小、又纯展示不修改,用 index 其实也行——但只要涉及增删改,还是老老实实用稳定 id 吧,省得后面踩坑。
点赞 4
2026-02-27 17:20