考虑如下代码:
function InputItem({ name }) {
const [value, setValue] = useState("");
return (
<div>
<span>{name}: </span>
<input value={value} onChange={e => setValue(e.target.value)} />
</div>
);
}
function App() {
const [list, setList] = useState([
{ id: 1, name: "Tom" },
{ id: 1, name: "Jerry" },
]);
return (
<div>
{list.map(item => (
<InputItem key={item.id} name={item.name} />
))}
</div>
);
}
key相同会发生什么?
首先输入框 1 输入 “A”,输入框 2 输入 “B”,然后执行setList颠倒数组的两项
你会发现两个<InputItem/>颠倒了,但是第一个输入框里还是“A”,第二个输入框里还是“B”
为什么会这样呢?
React 依赖 key 来识别哪些元素被添加、删除或修改
如果两个元素的 key 相同,React 就无法唯一标识每个节点,导致如下问题:
- React 将两个
<InputItem>互换 - 发现两个节点的 key 都是
1 - 所以虽然节点互换了,但DOM里面的状态都复用原来的位置
- 结果是:输入框里的内容没有互换
因此key相同会发生DOM的状态错乱
那我用index作为key可以吗?下面这样:
function InputItem({ name }) {
const [value, setValue] = useState("");
return (
<div>
<span>{name}: </span>
<input value={value} onChange={e => setValue(e.target.value)} />
</div>
);
}
function App() {
const [list, setList] = useState([
{ id: 1, name: "Tom" },
{ id: 1, name: "Jerry" },
]);
return (
<div>
{list.map((item, index) => (
<InputItem key={index} name={item.name} />
))}
</div>
);
}
依然还是会发生原来的问题,输入框里的内容没有互换
因为互换以后index没有互换啊,还是原来的啊
现在我们知道了,不管是key相同或者用index作为key,都可能会造成DOM的状态混乱
那我不定义key会怎样,不定义key那key就都是undefined了,也会回到key相同的局面
因此我们定义key必须确保key的唯一性