In response to a state change, I want to trigger another state change. Is that inherently a bad idea?
The specific sort of scenario is that the component is modeled as a state machine that renders different information according to the value of this.state.current_state
. But external events can prompt it to experience a state transition, via changes to it's state through a flux store. Here's a contrived scenario to get the idea across:
I think the correct lifecycle method to do this would be shouldComponentUpdate
. Something to this effect:
shouldComponentUpdate: function(nextProps, nextState) {
if (nextState.counter > 4 && this.state.current_state !== DISPLAY_MANY) {
this.setState({ current_state: DISPLAY_MANY });
}
return true;
}
In some child component, counter
may get incremented, so rather than inferring what it would display based on the value of some counter
variable, I'd like to encode the states explicitly.
The real scenario is more complicated than this, but hopefully this scenario is detailed enough to get the idea across. Is it OK to do what I'm thinking?
EDIT: fixed code example to avoid triggering infinite loop by adding extra state condition
Calling this.setState multiple times only re-renders the component once, the value of nextState (inside shouldComponentUpdate which is also called once only) is equal to value passed to setState on the first call. shouldComponentUpdate is called each time this.setState is called & the component re-renders if it returns true.
Use the setState() method everywhere else; doing so accepts an object that eventually merges into the component’s existing state. For example, the following does not rerender a component: Instead, use setState(). How do I use setState() in React?
Whereas the forceUpdate () method re-render the component without even changing the state or props. When we call forceUpdate (), it will re-render the component and skip shouldComponentUpdate () method. Note: We should try to stop using forceUpdate () wherever possible and read from this.props and this.state during rendering.
That is because setState () calls the render () function of your component. You can see that after the render () function, the componentDidMount () function will be called by React.
shouldComponentUpdate
is intended specifically to determine if the component should update at all. To do things like:
if (nextState.counter == this.state.counter && nextProps.foo == this.Props.foo) {
return false;
}
componentWillReceiveProps
is for responding to external (props) changes. There is no equivalent componentWillReceiveState
, as pointed out in the docs. Your component (and only your component) triggers it own state changes, usually through one or more of the following events:
getInitialState
componentWillReceiveProps
<input>
fields etc, e.g. in custom onChangeInput()
functions in your component.getStateFromStores()
, where state is updated.I guess it doesn't make sense to have one function inside a component to create a state change, and then another function inside the same component to intervene before state is updated..
In your case, you could move the logic (to determine if state needs to be updated) to a getStateFromStores()
function where you handle store updates.
Or, you could simply leave it in state, and change your render function, so that it renders differently if counter > 4.
No. Please use componentWillReceiveProps
instead. It has the same signature of shouldComponentUpdate
and you're safe to call this.setState
there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With