React 16.04 depreciated componentWillReceiveProps lifecycle method. You have to use UNSAFE_componentWillReceiveProps to continue to use it. They also introduced a static method called getDerivedStateFromProps. It is not exactly a replacement for componentWillReceiveProps. As the name suggests, it is used to derive the state from props. So whatever you return from getDerivedStateFromProps will be the new state.

Using getDerivedStateFromProps

getDerivedStateFromProps is a static method. Syntax is as follows

class MyComponent extends React.Component {
  static getDerivedStateFromProps(props,state){
    return {
       name: "techdomain"
    }
  }
}

Here we are returning

{
 name: "techdomain"
}

inside getDerivedStateFromProps. So the state will always be {name:"techdomain"}. This lifecycle method is called every time before render. This can be a issue if you want to copy props to state for only one time.

Please note that copying props to state is not encouraged, and in many cases, it can be overcomed by using memoization technique, fully controlled components or componentDidUpdate method. This post is not about when to not use getDerivedStateFromProps method (I guess you would have heard it many times to not use it by now).

Copying initial object from props to state

So as discussed, we want have some props passed from parent component, and we want it to set to state only for the initial load. In order to check if the state has been copied or not, we will use another state variable called initDone. We will set it to true once the state has been copied.

For example, suppose that NameInput is the child component of some form component. And you want to set the initial name to the NameInput component.

class NameInput extends React.Component {
  static getDerivedStateFromProps(props,state){
    if(props.name && !state.initDone){ // check for initDone as well as props.name
       return {
         name: props.name,
         initDone: true // set it to true so that it will not be called again
       }
    }
  }
}

So now we have copied the props.name to state.name. If the value of state changes inside NameInput component, then copy will not happen again as initDone is true.

Here is the jsfiddle

You might argue that the above example is misuse of getDerivedStateFromProps. And yes it is! We could have avoided using getDerivedStateFromProps, and simply created a controlled component. So there will be no state inside the NameInput component. It will simply set the input value as props.name.

But we cannot generalize all the cases. There might be scenarios where getDerivedStateFromProps is genuinely required. And this technique, mentioned above, to copy the state only one time initially might be helpful.