Alan Jenshen
Alan Jenshen

Reputation: 3239

Use setTimeout after setState in react to avoid async issue

I often do this

this.setState({
something: this.state.something + 1
})

setTimeout(() => { this.props.somefunction(this.state.something) },100);

Is this even correct? but this at least solved my problem. If I don't do timeout here somefunction which is declared in my parent component will received an undefined param. I guess doing this.props.somefunction() is executed before setState is done?

Upvotes: 2

Views: 3171

Answers (3)

Tom Van Rompaey
Tom Van Rompaey

Reputation: 3586

The official documentation recommends that you put your "callback logic" inside componentDidUpdate() instead of the seconds parameter of setState().

The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered. Generally we recommend using componentDidUpdate() for such logic instead.

Here's an example how to do this:

this.setState({
  something: this.state.something + 1
})

componentDidUpdate(prevProps, prevState) {
  if (this.state.something !== prevState.something) {
    this.props.somefunction(this.state.something); // the state of something has changed -> execute callback function 
  }
}

Upvotes: 1

pushkin
pushkin

Reputation: 10209

No, that's not a good pattern. async functions should have a callback parameter that you can use, and looking at the docs, there is one.

Make your function the second parameter to setState.

this.setState({...}, () => {
    this.props.somefunction(this.state.something);
}

The reason using setTimeout here is bad, is because you're taking a chance. You're saying, "I don't know how long this async operation will take, but I'm don't expect it to take longer than 100 ms, so I'm going to take a chance." But of course, you have no idea how long it will take.

The callback parameter ensures that the function will run after the async operation completes, so you don't need to cross your fingers.

Upvotes: 5

Phiroze Noble
Phiroze Noble

Reputation: 303

Using setTimeout to run actions on action complete is generally bad practice and the devs at facebook definitely took that into consideration. Which is why they have a callback method as the second argument for setState.

setState({ something: newState }, () => {
   // Run dependant actions here
})

Upvotes: 0

Related Questions