Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对animationend问题作出反应_Javascript_Css_Reactjs - Fatal编程技术网

Javascript 对animationend问题作出反应

Javascript 对animationend问题作出反应,javascript,css,reactjs,Javascript,Css,Reactjs,我在React中创建了一个简单的通知服务,遇到了一个非常奇怪的问题,我找不到任何提及或解决方案 我的组件有一个通知消息数组。每个“通知”都有一个“onClick”和“onAnimationEnd”绑定,该绑定调用一个函数,该函数将从通知数组中删除它们。其基本思想是通知将逐渐消失(使用CSS动画),然后被删除,或者允许用户手动单击通知以删除它 有趣的bug如下所示。如果添加两个通知,第一个通知将触发其onAnimationEnd并删除自身。剩下的通知将突然跳转到css动画的末尾,并且永远不会触发自

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

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

有趣的bug如下所示。如果添加两个通知,第一个通知将触发其onAnimationEnd并删除自身。剩下的通知将突然跳转到css动画的末尾,并且永远不会触发自己的onAnimationEnd

更奇怪的是,如果您添加四个通知,其中正好有两个会出现上述错误,而另外两个功能正常

还值得一提的是,如果您创建了两个通知,并单击其中一个,然后手动将其删除,其余的通知将正常运行并触发其自己的onAnimationEnd功能

因此,我不得不得出结论,通过数组的循环和onAnimationEnd触发器的某些组合在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')
);
工作代码笔链接
您正在使用数组索引作为组件键:

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

数组索引只能在万不得已的情况下用作组件键。

Dylan感谢您的回复。但是,如果是这种情况,为什么删除通知元素的onClick版本可以正常工作?他们基本上在做完全相同的事情。onClick将删除元素,并导致重新计算索引键,但动画在这种情况下继续运行很难100%确定,因为我无法100%确定React如何使用键进行优化,但可以想象这样的情况:(生成通知0)->(生成通知1)->(提前解除通知0)->(通知1继承了0的
onAnimationEnd
,因为React认为它实际上是0)。现在想象一下这种情况,而不手动取消:(0的
onAnimationEnd
激发)->(1继承了0的
onAnimationEnd
,但动画已经结束,因此它永远不会激发)。如果您的通知在文本中更复杂,我保证只使用
onClick()就会发生奇怪的事情
,它们现在并不明显,因为您的所有通知都只是“测试”。不过,您不必相信我的话,试试看!@mls3590712在这里,我想到了一个演示的方法。在您的代码笔中,生成1个通知,等待~4秒,然后生成第二个通知。生成第二个通知后立即生成第二个通知n、 取消第一个通知(位于顶部的通知)。剩余的通知将立即在淡入淡出的过程中进行一部分并提前消失。我可以确认您的唯一密钥解决方案确实解决了问题。发生这种奇怪的行为(正好有一半不起作用,但另一半起作用)让我很恼火。感谢您的洞察力。
        {this.state.notifications.map(
          (notification,i) => {
            return (
              <div onAnimationEnd={()=>this.remove(notification)} 
                   onClick={() => this.remove(notification)}
                   className="notification" 
                   key={i}>
                   {notification}
              </div>
            )
          }
        )}
add = () => {
    this.setState({notifications: [...this.state.notifications, Math.random().toString()]})
}

...

key={notification}