Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

this.setState() does not work in componentWillReceiveProps

Tags:

reactjs

I have a login page in which I am using componentWillReceiveProps to route to the next page. But the state that I am setting inside componentWillReceiveProps does not seem to set.

This is my componentWillReceiveProps method :

  componentWillReceiveProps(nextProps) {
      if (nextProps.isAuthenticated === true) {
          browserHistory.push('/home');
      } else {
        console.log("this.props :::" + JSON.stringify(this.props))
          console.log("this.state :::" + JSON.stringify(this.state))
          console.log("nextProps :::" + JSON.stringify(nextProps))
          this.setState({
              errorMessage: nextProps.authenticationError
          })
          console.log("this.state :::" + JSON.stringify(this.state))
      }
  }

The console output I am getting is this :

this.props :::{"authenticationError":null}  
this.state :::{"username":"35135","password":"3135","errorMessage":""}  
nextProps :::{"isAuthenticated":false,"authenticationError":"Could not find user in DB."}  
this.state :::{"username":"35135","password":"3135","errorMessage":""}  

Here even after setting the state, my state has not changed.

Please tell me what is it that I'm doing wrong.

EDIT: I have this component which is ErrorText , which takes in the errroMessage property.

<ErrorText errorMsg={this.state.errorMessage}></ErrorText>
like image 318
v1shnu Avatar asked Feb 20 '17 13:02

v1shnu


2 Answers

setState() is an asynchronous operation, so it doesn't take effect immediately:

setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state [...]

Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately.

setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback [...], either of which are guaranteed to fire after the update has been applied.

Here's an example of a setState callback in your context:

this.setState(
    { errorMessage: nextProps.authenticationError },
    function() {
        console.log( 'this.state ::: ' + JSON.stringify( this.state ) );
    }
);
like image 145
keul Avatar answered Sep 29 '22 07:09

keul


Refer to same stackoverflow question:

Why Calling react setState method doesnt mutate the state immediately

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

like image 23
Robsonsjre Avatar answered Sep 29 '22 07:09

Robsonsjre