gpt4 book ai didi

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

转载 作者:技术小花猫 更新时间:2023-10-29 10:25:02 26 4
gpt4 key购买 nike

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

Here's a jsbin to illustrate this problem .尝试按“添加”按钮以验证插入动画确实按预期工作,然后单击任何项​​目旁边的“x”以查看列表最后一项动画而不是您尝试删除的元素的问题。

是我在设置 TransitionGroup 时做错了什么,还是我在 CSS 过渡定义中遗漏了什么?

最佳答案

您遇到此问题是因为您使用 index 作为 key :

let nodes = items.map((item, index) => {
let idx = index
return (<Item key={index} value={item} index={index} _delete={this._onDelete}/>)
})

React 在虚拟 DOM 比较期间使用 key 属性来确定删除了哪个元素,但索引永远无法充分满足此目的。

考虑这个例子:你从下面的数组开始,它产生了下面的 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>

然后假设您删除了索引 2 处的元素。您现在拥有以下数组和以下 DOM 结构:

const arr = [2, 4, 8];

<li key={0}>2</li>
<li key={1}>4</li>
<li key={2}>8</li>

注意 8 现在位于索引 2 中; React 发现这个 DOM 结构与上一个的不同之处在于缺少键为 3li,因此将其删除。因此,无论您删除了哪个数组元素,生成的 DOM 结构都将缺少带有键 3li

解决方案是为列表中的每个元素使用唯一标识符;在实际应用程序中,您可能需要使用 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}/>)
})

// ...
}
}

工作示例:http://jsbin.com/higofuhuni/2/edit

关于css - 删除一项会导致 React 删除最后一个 DOM 节点,而不是与该元素关联的节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30406811/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com