我正在尝试动态处理输入列表。但是当我在输入中放入一些内容并从列表中删除一个内容时,我有一个不受欢迎的行为。删除了正确的项目,但最后一个位置的项目采用上一项目的状态。
var ListItem = React.createClass({
getInitialState: function() {
return {
content: ''
}
},
handleChange: function(e) {
this.setState({
content: e.target.value
})
},
render: function() {
return <div>
<input type="text" onChange={this.handleChange} />
</div>
}
});
var App = React.createClass({
getInitialState : function(){
return {
items : []
}
},
deleteElement: function(index, e) {
this.setState({
items: this.state.items.filter(function (e, i) {
return i !== index;
})
});
},
addElement: function() {
this.setState({
items: this.state.items.concat(<ListItem />)
});
},
render: function() {
var list = this.state.items.map(function(item, i) {
return <li key={ i }>
<p onClick={ this.deleteElement.bind(this, i) }>(-)</p>
<span>{ item }</span>
</li>
}, this);
return <div>
<ul>{ list }</ul>
<p onClick={ this.addElement }>(+)</p>
</div>
}
});
ReactDOM.render(
<App />,
document.getElementById('container')
);
&#13;
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
&#13;
我认为问题可能与我的列表键有关,但我不明白为什么。如何在不改变任何状态的情况下删除列表元素?
由于
答案 0 :(得分:3)
在渲染中迭代时,React重用组件实例(出于显而易见的性能原因)。为了区分实例,使用了道具key
。
在您删除元素的情况下,索引会移动,因此您会混淆key -> instance
关联。因此,删除元素之后的列表项不再与正确的实例相关联,这就是为什么某些列表元素似乎具有前一个元素的状态。
要避免此问题,您应该永远不要将索引用作关键支柱。请改为使用数据实例的唯一标识符。
在您的情况下,您可以在添加新元素时生成唯一标识符,并将其用作键。
有关列表如何在React中工作的详细信息,请阅读:https://facebook.github.io/react/docs/lists-and-keys.html