您遇到此问题的原因是您将其
index用作密钥:
let nodes = items.map((item, index) => { let idx = index return (<Item key={index} value={item} index={index} _delete={this._onDelete}/>)})React
key在虚拟DOM差异期间使用该属性来确定删除了哪个元素,但是索引永远无法充分满足此目的。
考虑以下示例:从以下数组开始,这将导致以下DOM结构:
const arr = [2, 4, 6, 8];<li key={0}>2</li><li key={1}>4</li><li key={2}>6</li><li key={3}>8</li>然后想象一下您删除了index处的元素
2。现在,您具有以下数组和以下DOM结构:
const arr = [2, 4, 8];<li key={0}>2</li><li key={1}>4</li><li key={2}>8</li>注意,
8现在位于index中
2;React认为此DOM结构与最后一个DOM结构之间的区别是缺少
liwith键
3,因此将其删除。因此,无论您删除了哪个数组元素,生成的DOM结构都将缺少
liwith键
3。
解决方案是为列表中的每个项目使用唯一的标识符;在现实生活中的应用程序中,您可能需要使用
id字段或其他一些主键;对于这样的应用,您可以生成一个递增ID:
let id = 0;class List extends Component { constructor() { this.state = { items: [{id: ++id, value: 1}, {id: ++id, value: 2}] } // ... } _onClick(e) { this.state.items.push({id: ++id, value: Math.round(Math.random() * 10)}) this.setState({items: this.state.items}) } // ... render() { let items = this.state.items let nodes = items.map((item, index) => { let idx = index return (<Item key={item.id} value={item.value} index={index} _delete={this._onDelete}/>) }) // ... }}


