文章首发于博客
之前在写react的时候,当我们做map循环的时候,当我们没有一个唯一id来标识每一项item的时候,我们可能会选择使用index
data.map((item, index) => { return
但是其实当你使用index来作为唯一key的时候,其实是由一个大坑的,什么坑呢?必须坑了你才知道,来看下面的这种情况:
class App extends React.Component{ constructor(props) { super(props) this.state = { list: [{id: 1,val: 'aa'}, {id: 2, val: 'bb'}, {id: 3, val: 'cc'}] } } click() { this.state.list.reverse() this.setState({}) } splice() { this.state.list.splice(1,1) this.setState({}) } render() { return (
delete
reverse
{ this.state.list.map(function(item, index) { return ( ) }.bind(this)) } 页面渲染好了之后,3个input输入框依次输入1,2,3: 当我们用index作为key的时候,点击reverse会发现,input输入框还是1,2,3顺序显示,但是这并不符合我们的预期,控制台中此时打印的也是update; 当我们用对象中的id作为key的时候,点击reverse,此时神奇的事情发生了,input输入框变成了3,2,1,符合我们的预期,控制台此时打印的也是update;
为什么会这样呢?
当我们传入index作为key时,此时的key为0,1,2, 当我们点击reverse重新排序后,index传进去的key还是0,1,2,此时react比较key=0时,发现只需要更新子节点的值就可以,于是只把item替换成了cc,而input则相反, 当我们传入id作为index的时候,,点击reverse后,此时的key变成了3,2,1,根据react的diff算法,react还是能分辨出只需要移动子节点即可完成更新,因此input也随之变化。
那说了这么多,其实对于index作为key我们是不推荐的,除非你能够保证他们不会发生变化。
参考文献 , 有问题可以在下方留言,感谢star