删除一项会导致React删除最后一个DOM节点,而不是与该项目关联的节点

我试图使用ReactCSSTransitionGroup为列表插入和删除创建动画,但是删除动画总是只对列表的最后一项设置动画,而不是要删除的动画。

这是一个jsbin来说明这个问题。尝试按“添加”按钮以验证插入动画确实按预期工作,然后单击任何项​​目旁边的“

x”,以查看列表中最后一项被动画化而不是您尝试删除的动画的问题。

设置TransitionGroup时我做错了什么吗?还是我在CSS过渡定义中丢失了某些东西?

回答:

您遇到此问题的原因是您将其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}/>)

})

// ...

}

}

以上是 删除一项会导致React删除最后一个DOM节点,而不是与该项目关联的节点 的全部内容, 来源链接: utcz.com/qa/428920.html

回到顶部