gpt4 book ai didi

javascript - React OnAnimation结束问题

转载 作者:行者123 更新时间:2023-11-29 23:01:27 24 4
gpt4 key购买 nike

我在 React 中做一个简单的通知服务,遇到了一个非常奇怪的问题,我找不到任何提及或解决方案。

我的组件有一组通知消息。每个“通知”都有一个“onClick”和“onAnimationEnd”绑定(bind),它们调用一个函数将它们从通知数组中删除。基本思想是通知会逐渐消失(使用 CSS 动画)然后被删除,或者允许用户手动单击通知以将其删除。

有趣的错误如下。如果您添加两个通知,第一个将触发其 onAnimationEnd 并自行删除。剩余的通知会突然跳到它的 css 动画的末尾并且永远不会触发它自己的 onAnimationEnd。

更奇怪的是,如果你添加四个通知,恰好其中两个会出现上述错误,而另外两个可以正常运行。

另外值得一提的是,如果你创建了两个通知,然后点击一个两次手动删除它,剩下的通知将正常运行并触发它自己的 onAnimationEnd 功能。

因此我不得不得出结论,循环遍历数组和 onAnimationEnd 触发器的某种组合在 react 中以某种方式被窃听,除非有人可以指出这个问题的解决方案。

react 代码

class Test extends React.Component {
constructor (props) {
super(props)
this.state = {
notifications: []
}
}

add = () => {
this.setState({notifications: [...this.state.notifications, 'Test']})
}

remove = (notification) => {
let notificationArray = this.state.notifications
notificationArray.splice(notificationArray.indexOf(notification), 1)
this.setState({notifications: notificationArray})
}

render() {
return (
<div>
<button onClick={this.add}>Add Notification</button>
<div className="notification-container">
{this.state.notifications.map(
(notification,i) => {
return (
<div onAnimationEnd={()=>this.remove(notification)}
onClick={() => this.remove(notification)}
className="notification"
key={i}>
{notification}
</div>
)
}
)}
</div>
</div>
);
}
}


ReactDOM.render(
<Test />,
document.getElementById('root')
);

CSS

.notification-container {
position: fixed;
bottom: 20px;
right: 20px;
width: 200px;
}

.notification {
border: 1px solid;
box-shadow: 0 10px 20px rgba(0,0,0,0.2), 0 6px 6px rgba(0,0,0,0.25);
color: white;
background: rgba(0,0,0,0.75);
cursor: pointer;
padding: 10px;
margin-top: 10px;
user-select: none;
animation: fade 7s linear forwards;
}

@keyframes fade {
0% {
transform: translate(100%,0);
}
2% {
transform: translate(-20px, 0);
}
5% {
transform: translate(0,0);
}
20% {
opacity: 1;
}
100% {
opacity: 0.25;
}
}

工作代码笔链接 https://codepen.io/msorrentino/pen/xeVrwz

最佳答案

您正在使用数组索引作为组件键:

        {this.state.notifications.map(
(notification,i) => {
return (
<div onAnimationEnd={()=>this.remove(notification)}
onClick={() => this.remove(notification)}
className="notification"
key={i}>
{notification}
</div>
)
}
)}

当您这样做时,React 无法正确检测您的组件何时被移除。例如,通过删除索引 0 处的元素,并将索引 1 处的元素移动到它的位置,React 将认为具有键 0 的元素只是被修改而不是删除。这可能会产生各种副作用,例如您所看到的。

尝试使用唯一标识符(如果有的话),否则使用某种递增键。

要在您的 codepen 中真正快速地测试这个,请更改这些位(当然,我实际上不建议使用您的消息作为您的 key ):

add = () => {
this.setState({notifications: [...this.state.notifications, Math.random().toString()]})
}

...

key={notification}

数组索引仅应作为最后的手段用作组件键。

关于javascript - React OnAnimation结束问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55525769/

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