Ad

Calling SetState() In A Function, And Proceeding To The Next Sibling Function After State Has Changed- Is It Possible?

let say I've got something like this:

In context provider:

toggleLogin(isLoggedIn) {
     this.setState({
         isLoggedIn: isLoggedIn
     });
}

In login component using context:

(....)
this.props.context.toggleLogin(true);
this.props.history.push("/"); 
(....)

I want this.props.history.push("/") or any else function I'll put after toggleLogin() execute only when toggleLogin function finishes updating state. Right now it's working good.

But I think because setState is async, under the hood it works like:

  1. execute toggleLogin
  2. start executing setState in toggleLogin
  3. execute this.props.history.push("/")
  4. finish setState in toggleLogin

And it's working in my case because state is set really fast.

But because its working it seems that's it's working this way:

  1. execute toggleLogin
  2. execute setState
  3. execute this.props.history.push("/")

I'm checking isLoggedIn state in "/" route component so thats why I want it to execute only after setState is finished. This is another component so I can't use setState callback.

Is this.props.history.push("/") really executed after toggleLogin is finished? If not, how can I make it do this? I don't find making toggleLogin async and awaiting setState and then using then() in login component a good idea - maybe I'm wrong, I'm just starting in ReactJS.

Can anyone enlighten me with right path of doing this? Thanks

Ad

Answer

setState is asynchronous and there is no guarantee that's gonna be finished when you call history.push. To make sure all updates are done before executing something use the second argument of setState which allow us to pass a callback to execute after the state's update. You could pass this callback to toggleLogin

this.props.context.toggleLogin(true, () => this.props.history.push('/'))

And in toggleLogin

toggleLogin(isLoggedIn, cb) {
     this.setState({
         isLoggedIn: isLoggedIn
     },  cb);
}
Ad
source: stackoverflow.com
Ad