Updating React Component state from props

There comes a time when the state we’re storing within our React Component needs to be updated, for example I have a ToggleButtonGroup which stores the state for the currently pressed/selected child item (i.e. you press a button in the group and the other’s deselect etc. basically a radio button).

When the component is created we might set our state from the properties like this

constructor(props) {
   super(props);

   this.state = { selected: this.props.selected }    
}

but the constructor is not called again, so what if our container component needs to change the state in our ToggleButtonGroup, so that when the properties are updated so that the ToggleButtonGroup reflects the property changes in the state.

Note: without some code in place to handle prop to state synchronisation will likely have state out of sync with expected values/behaviour.

We can use the componentDidUpdate function like this to update our state

componentDidUpdate(prevProps) {
   if(this.props.selected != prevProps.selected) {
      this.setState({selected: this.props.selected});
   }  
}

This occurs after the properties have been updated. See componentDidUpdate for more information.

You should have the guard to only change the state if the property actually changed.

componentDidUpdate is not called

The likely reason that the componentDidUpdate function is not called is if shouldComponentUpdate returns false.

getDerivedStateFromProps

An alternative to componentDidUpdate is to write a static function named getDerivedStateFromProps into your components/class. This is invoked before the render function for both initial and subsequent updates. I’ve not used this so best to read more at getDerivedStateFromProps.

Deprecated method

This method has been deprecated, but in case you come across it, we can use the component lifecycle function componentWillReceiveProps to achieve the same synchronisation of props to state. For example

componentWillReceiveProps(newProps) {
   if(newProps.selected != this.props.selected) {
      this.setState({selected: newProps.selected});
   }
}