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