示例
先看一段代码
constructor() {
super();
this.state = {
sort: [{
name: 'a'
}, {
name: 'b'
}, {
name: 'c'
}]
}
}
...
render() {
return (
<ul>
{this.state.sort.map((item, index) => {
return <li key={index}>{item.name} <input type="text"/></li>
})}
</ul>
);
}
...
是不是很眼熟?在很长一段时间,我都是这么设置key来消除react的warning的,然后突然有次发现会出现这样的情况,见下图:
出现这个情况,是因为react是以key来唯一标识组件的,当发现update前和update后key值没有变化,react就会认为update前后组件是同一个,进而只会对内部的属性进行修改。拿上面的例子来讲,就是react会作出这样的判断:
- 检测key值,发现都是0,判定组件为同一个;
- 检测item.name部分,发现有变化,重新渲染这部分;
- 检测input,发现不依赖props,所以不进行重新渲染;
优化示例
这次我们将key设置为一个特殊字段,保证其唯一性,假设item.name是唯一的。
render() {
return (
<ul>
{this.state.sort.map((item, index) => {
return <li key={item.name}>{item.name} <input type="text"/></li>
})}
</ul>
);
}
然后这次再看效果
这次修改后,react在拿到key后,可以判断出key值和之前不一,再进行对比,发现组件的位置进行了交换,所以做出了符合我们预期的行为。
总结
渲染数组是非常常见的需求,但是选择哪个字段作为key需要慎重考虑,一点要保证其唯一性,尽量避免使用array的索引值作为其key值。