Reputation: 3239
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
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
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
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