Reputation: 103
The react docs mention that calls to setState
are enqueued, and do not happen immediately. Does react make any guarantees that setState
enqueued inside componentWillReceiveProps
will execute before the next component render? Are either of these scenarios more likely than the other?
props change > componentWillReceiveProps called > setState enqueued > setState runs > render (which includes new state)
props change > componentWillReceiveProps called > setState enqueued > render > setState runs > re-rendered
Or, are both of these scenarios equally likely? Meaning does React not make any guarantees when setState will run relative to component lifecycle methods?
Here is a ES2015 code excerpt of my example:
import React from 'react';
class Widget extends React.Component {
componentWillReceiveProps() {
this.setState({foo: 'bar'});
}
render() {
return <div>
<a onClick={(e) => {
e.preventDefault();
this.props.triggerExternalPropsChange();
}}>
Click me to trigger new props
</a>
</div>;
}
}
Where triggerExternalPropsChange
passes new props to the Widget
component.
Upvotes: 8
Views: 8065
Reputation: 268255
The only reason componentWillReceiveProps
exists is to give the component an opportunity to setState
. So yes, any state you set synchronously in it will be processed together with the new props. There won’t be two renders in this case, just one.
Upvotes: 26
Reputation: 2279
It's 1.
Calling setState() in componentWillReceiveProps() is an exception in the sense of executing state update before the component renders, so you will get both props changes and state changes applied in the same render.
Upvotes: 1
Reputation: 16441
Yep, both are likely. React will try to render anytime it gets new props or state and because it does dom diffing, it tries to render as often as possible. You have options to control it though, using shouldComponentUpdate
you can check and wait until both props and state have been updated before rendering.
Upvotes: 0