We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
之前在写react的时候,当我们做map循环的时候,当我们没有一个唯一id来标识每一项item的时候,我们可能会选择使用index
data.map((item, index) => { return <li key={index}>{item}</li> })
但是其实当你使用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 ( <ul> <div onClick={this.splice.bind(this)}>delete</div> <div onClick={this.click.bind(this)}>reverse</div> { this.state.list.map(function(item, index) { return ( <Li key={index} val={item.val}></Li> ) }.bind(this)) } </ul> ) } } class Li extends React.Component{ constructor(props) { super(props) } componentDidMount() { console.log('===mount===') } componentWillUpdate(nextProps, nextState) { console.log('===update====') } render() { return ( <li> {this.props.val} <input type="text"></input> </li> ) } }
页面渲染好了之后,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我们是不推荐的,除非你能够保证他们不会发生变化。
参考文献 index as a key is an anti-pattern
The text was updated successfully, but these errors were encountered:
mark
Sorry, something went wrong.
No branches or pull requests
之前在写react的时候,当我们做map循环的时候,当我们没有一个唯一id来标识每一项item的时候,我们可能会选择使用index
但是其实当你使用index来作为唯一key的时候,其实是由一个大坑的,什么坑呢?必须坑了你才知道,来看下面的这种情况:
页面渲染好了之后,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我们是不推荐的,除非你能够保证他们不会发生变化。
参考文献
index as a key is an anti-pattern
The text was updated successfully, but these errors were encountered: