简体   繁体   中英

Updating state within setTimeout (React & React-Native)

What I've been trying to achieve are to update state and to update the same state again, based on Javascript's timer.

The reason why I can't achieve this seems to be the nature of state in React.js.

Here is a snippet of my experimentation...

render() {
    if (this.props.hasError) {
        setTimeout(function(){this.setState({showWarning: true}); }.bind(this), 3000);
    }
    return (
      <View>
        <Blah warning={this.state.showWarning} />
      </View>
    );
}

So, the objective is to change state for only just a few seconds if there is a specific props provided .

This approach seems to hit the limit of updating states, if this.props.hasError gets updated too frequently.

Apologies if this question is too basic. Any suggestion will be appreciated.

You shouldn't update your state in render() function. If you do so, you will end up in an infinite loop, that's why you got that error. You need to use:

componentWillReceiveProps(nextProps){
    if (this.nextProps.hasError) {
        setTimeout(function(){this.setState({showWarning: true}); }.bind(this), 3000);
    }
}

This should resolve your issue.

you are using function inside timeout this will change its scope use arow function

btw i have modify your code accordingly

componentWillReceiveProps(nextProps) {
    if(nextProps.hasError != this.props.hasError){
        this.setState({
            showWarning:nextProps.hasError 
        });
        setTimeout(()=> {
            this.setState({
                showWarning:!this.props.showWarning
            });
        }, 3000);
    }
}


render() {
    return (
      <View>
        {this.state.showWarning?<Blah warning={this.state.showWarning} />:null}
      </View>
    );
}

There are two purposes. One is to change the background color of this component for 3 seconds, the other is to show a message, which is located in (again, for 3 seconds)

Since you only want these changes to show for 3 seconds, you have to set them first, and then set the state to its opposite after 3 seconds using setTimeout.

Judging from your code, this.props.hasError is a boolean so we can set showWarning with that initially:

constructor(props){
  super(props);
  this.state = {showWarning: this.props.hasError}
}

When the component renders, it will show the current state and after 3 seconds, we will change the state:

componentDidMount(){
  setTimeout(() => {
    this.setState({showWarning: false});
  }, 3000);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM