Javascript 反应,两个组件运行两次超时卸载;相同的卸载会被调用两次

Javascript 反应,两个组件运行两次超时卸载;相同的卸载会被调用两次,javascript,reactjs,Javascript,Reactjs,TL;DR:这种情况正在发生: 为什么它们同时消失?应该只应用于一个组件的样式似乎同时应用于两个组件 这个版本:他们是红色的,而不是不透明度的变化,使问题更清楚;红色样式将应用于两个通知,即使只有一个通知超时 安装通知组件时,它会为可变延迟设置超时: componentDidMount = () => { let timeout = parseInt(this.props.decay) || 2000 this.setState({

TL;DR:这种情况正在发生: 为什么它们同时消失?应该只应用于一个组件的样式似乎同时应用于两个组件

这个版本:他们是红色的,而不是不透明度的变化,使问题更清楚;红色样式将应用于两个通知,即使只有一个通知超时

安装通知组件时,它会为可变延迟设置超时:

componentDidMount = () => {
        let timeout = parseInt(this.props.decay) || 2000
        this.setState({ 
            dismissTimeout: setTimeout(() => {
                this.fadeOutFunction();
                setTimeout(() => {
                    this.dismiss();
                }, 125)
            }, timeout)
        })  
    }   
}
淡出动画将在100毫秒内发生,然后卸载组件:

fadeOutFunction = () => {
    let opacity = Math.floor(this.state.style.opacity * 10) 
    if ( opacity > 0) {
        opacity -= 1;  
        setTimeout(() => { this.fadeOutFunction() }, 10) 
    }   
    let newState = Object.assign({}, this.state.style)
    newState.opacity = opacity / 10
    this.setState({ style: newState })
} 
Dismise函数连接到父组件中的此函数,父组件管理通知组件的数据“模型”数组:

dismiss = () => {
    this.props.dismiss(this.props.code);
} 

// in parent
dismissNotification = (code) => {
    this.setState({ notifications: this.state.notifications.filter (
        n => n.code != code
    )})
} 
设置了两个通知,一个为2000衰减,另一个为5000衰减

当第一个组件淡出时,会发生一些非常奇怪的行为;两个组件都会丢失其不透明度(设置为0),并且会为错误的组件调用卸载函数。。。疯狂的是,fadeOut函数继续调用“卸除”组件(5000ms组件,仍在DOM中)导致错误:

警告:无法对未安装的组件调用setState(或forceUpdate)。

但真正让我困惑的是,如果我检查
dismissNotification
,它会过滤掉正确的通知

更新:JSFIDLE现在复制错误:

但是没有任何问题!看看我的代码,我不认为有任何明显的区别,事实上,当我将淡出函数改为“将组件设置为红色”时:

makeRedFunction = () => {
    this.setState({ style: {backgroundColor: "red"} })
}
组件会在正确的时间更改其样式,并正确地消除错误

很抱歉,这有点含糊不清,我真希望我知道如何获得更多正确的信息,但是。。为什么设置不透明度不会在codefiddle上触发错误,而是会在我的应用程序中触发错误?为什么不透明度会导致这种奇怪的跨组件行为,而颜色不会

在我的项目中,我是否缺少一些对动画至关重要的依赖项?我已经看到有动画库,但有了这些简单的东西,我宁愿自己编写

**编辑:** 父组件的渲染

            {
                this.state.notifications.map( (n, idx) => {                                                                                                                       
                    return <Notification                                                                                                                                          
                        key={idx}                                                                                                                                                 
                        code={n.code}                                                                                                                                             
                        decay={n.decay}
                        dismiss={ () =>{this.dismissNotification(n.code)}}                                                                                                                        
                    > 
                        { n.message }                                                                                                                                             
                    </Notification>                                                                                                                                               
                })                                                                                                                                                                
            } 
{
this.state.notifications.map((n,idx)=>{
返回{this.dismissNotification(n.code)}
> 
{n.message}
})                                                                                                                                                                
} 

这是通知组件中的逻辑错误:

setTimeout(() => {
  this.fadeOutFunction();
  setTimeout(() => {  // <--- This part is uneccessary
   this.dismiss();
  }, 125)
}, timeout)     
setTimeout(()=>{
这个.fadeOutFunction();
setTimeout(()=>{//{
让timeout=parseInt(this.props.decation)| 2000
设置超时(()=>{
这个.fadeOutFunction();
},超时)
}
淡出功能=()=>{
让不透明度=Math.floor(this.state.style.opacity*10)
如果(不透明度>0){
不透明度-=1
setTimeout(()=>{this.fadeOutFunction()},10)
}
让newState=Object.assign({},this.state.style)
newState.opacity=不透明度/10
this.setState({style:newState})
}
解雇=()=>{
this.props.discover(this.props.code)
}
渲染(){
返回(
{this.props.children}
)
}
}
class Notification extends React.Component {
    constructor(props) {
    super(props)
    this.state = {
        style: { opacity: 1 }
    }
  }

  componentDidMount = () => {
    let timeout = parseInt(this.props.decay) || 2000

    setTimeout(() => {
      this.fadeOutFunction();
    }, timeout)     
  }

  fadeOutFunction = () => {
    let opacity = Math.floor(this.state.style.opacity * 10)
    if (opacity > 0) {
        opacity -= 1
      setTimeout( () => { this.fadeOutFunction() }, 10)
    }
    let newState = Object.assign({}, this.state.style)
    newState.opacity = opacity / 10
    this.setState({ style: newState })
  }

  dismiss = () => {
    this.props.dismiss(this.props.code)
  }

  render () {
    return(
         <div style={this.state.style}>{this.props.children}</div>
    )
  }
}