问题描述
我有一个名为 flash 的组件,它只在 DOM 中停留 5 秒(这是一条消息,通知用户他已成功发送帖子),我希望它开始淡出2 秒后离开,所以当它从 DOM 中移除 5 秒后,它的可见性已经设置为 0。 为了实现这一点,在父组件中,我 setTimeout() 并向 flash 组件发送一个包含设置为 true 的布尔值的道具,它有一个 if 等待该布尔值,当它得到它时,它为该组件分配一个新类以使其消失。这一切听起来很完美,但不幸的是它根本不起作用......我尝试更新 flash 组件中的类,但它也不起作用......也许你可以想出一些办法?我确信在 React 中使用预先安排的组件发送 flash 消息是一件小事,但我想不出任何方法!
父组件:
if(this.state.flashMessage){
flash = <Flash>{this.state.flashMessage}</Flash>
setTimeout(() => {
//here I send the component the prop 'close' after two seconds
flash = <Flash close>{this.state.flashMessage}</Flash>
},2000);
}
return (
<React.Fragment>
<div className={classes.postContainer}>
{posts}
<div className={classes.Card} onClick={this.showPostAdd}>
<img alt="add a post" src={addPostimage} />
</div>
</div>
{addPostActive}
{flash}
</React.Fragment>
);```
Here is the flash component
``` const flash = (props) => {
let classNames = [classes.Flash];
if(props.close){
classNames.push(classes.TestFlash);
}
return (
<div className={classNames.join(' ')}>
<p>{props.children}</p>
</div>
);
}
解决方法
渲染仅在更新组件时运行,并且 setTimeout 不会触发该更新。但是,更改状态值确实会触发组件的更新。
您应该做的是直接在 render 方法上打印 Flash 组件,并将 close 属性绑定到状态布尔值。 >
<Flash close={this.state.closeFlashMessage}>{this.state.flashMessage}</Flash>
我将超时函数放在 componentDidMount() 方法上。
componentDidMount() {
this.mounted = true;
setTimeout(() => {
//check the mounted state in case the component is disposed before the timeout.
if(this.mounted) {
//here I send the component the prop 'close' after two seconds
this.setState({ closeFlashMessage: true });
}
},2000);
}
//add this method to prevent any state management during the component's disposal
componentWillUnmount() {
this.mounted = false;
}
,
这不起作用,因为简单地设置 flash = ...
不会触发重新渲染。您需要在组件的状态中存储该信息并在那里更新它以使其正常工作。我认为这样的事情会奏效:
{this.state.flashMessage && <Flash close={this.state.isFlashMessageClosed}>{this.state.flashMessage}</Flash>
我也不建议直接在渲染方法中设置超时。这应该是由状态更改触发的副作用,因此我建议将其放在 componentDidUpdate
中,如下所示:
componentDidUpdate(prevProps,prevState) {
if(prevState.flashMessage !== this.state.flashMessage) {
// If the flash message changed,update state to show the message
this.setState({ isFlashMessageClosed: false });
setTimeout(()=>{
// Update state to close the message after 2 seconds
this.setState({ isFlashMessageClosed: true });
},2000);
}
}
希望这对你有用。