如何使用 setTimeout() 函数在一段时间后向组件发送新道具?

问题描述

我有一个名为 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);
  }
}

希望这对你有用。