Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

componentWillReceiveProps vs getDerivedStateFromProps

What exactly componentWillReceiveProps and getDerivedStateFromProps are subtle question for me. Because, I just came across to an issue while using getDerivedStateFromProps:

// Component 
state = {
  myState: []
}

// Using this method works fine:

componentWillReceiveProps(nextProps) {
  this.setState({
    myState: nextProps.myPropsState
  })
}

// But using this method will cause the checkboxes to be readonly:

static getDerivedStateFromProps(nextProps,prevProps) {
  const { myPropsState: myState } = nextProps
  return {
    myState
  }
}

// And here's checkbox
<input type="checkbox" id={`someid`} 
 onChange={(e) => this.handleMethod(e, comp.myState)} 
 checked={myState.indexOf(comp.myState) > -1} />

React version: 16.4.1

like image 726
Bhojendra Rauniyar Avatar asked Aug 03 '18 11:08

Bhojendra Rauniyar


People also ask

What is the replacement for componentWillReceiveProps?

The useEffect hook is also the equivalent of the componentWillReceiveProps or componentDidUpdate hooks. All we have to do is to pass in an array with the value that we want to watch for changes.

When should I use componentWillReceiveProps?

The componentWillReceiveProps() is invoked before our mounted React component receives new props. It is called during the updating phase of the React Life-cycle. It is used to update the state in response to some changes in our props.

Is componentWillReceiveProps deprecated?

With the release of React 16.3, some new lifecycle methods have been introduced, and release of React 17 will deprecate some lifecycle method. getDerivedStateFromProps is one of those newly introduced lifecycle method replacing componentWillReceiveProps , which has now become UNSAFE_componentWillReceiveProps .

What is getDerivedStateFromProps?

getDerivedStateFromProps is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing. This method exists for rare use cases where the state depends on changes in props over time.

Do I need componentWillReceiveProps?

ReactJS – componentWillReceiveProps() MethodThis method is used during the updating phase of the React lifecycle. This function is generally called if the props passed to the component change. It is used to update the state in response with the new received props.

Where is getDerivedStateFromProps used?

ReactJS – getDerivedStateFromProps() Method This method is called before the rendering or before any updation of the component. This method is majorly used to update the state, before the rendering of the component, which depends upon the props received by the component.


1 Answers

Finally, I resolved my issue. It was a painful debugging:

// Child Component

// instead of this
// this.props.onMyDisptach([...myPropsState])

// dispatching true value since myPropsState contains only numbers
this.props.onMyDispatch([...myPropsState, true])

This is because, I have two conditions: 1) on checkbox change (component) 2) on reset button pressed (child component)

I was needing to reset the states when reset button is pressed. So, while dispatching state to the props for reset button, I used a boolean value to know it's a change from the reset. You may use anything you like but need to track that.

Now, here in the component, I found some hints to the differences between componentWillReceiveProps and getDerivedStateFromProps after debugging the console output.

// Component
static getDerivedStateFromProps(props, state) {
    const { myPropsState: myState } = props
    // if reset button is pressed
    const true_myState = myState.some(id=>id===true)
    // need to remove true value in the store
    const filtered_myState = myState.filter(id=>id!==true)
    if(true_myState) {
      // we need to dispatch the changes to apply on its child component
      // before we return the correct state
      props.onMyDispatch([...filtered_myState])
      return {
        myState: filtered_myState
      }
    }
    // obviously, we need to return null if no condition matches
    return null
  }

Here's what I found the results of the console output:

  • getDerivedStateFromProps logs immediately whenever props changes

  • componentWillReceiveProps logs only after child propagates props changes

  • getDerivedStateFromProps doesn't respond to the props changes ( I meant for the dispatch changes as in the example code)

  • componentWillReceiveProps responds to the props changes

  • Thus, we needed to supply the changes to child component while using getDerivedStateFromProps.

The process of pasting true value in the state I require because getDerivedStateFromProps handle all the changes unlike componentWillReceiveProps handles only the child component dispatches the changes to the props.

By the way, you may use custom property to check if it is changed and update the value if getDerivedStateFromProps but for some reason I have to tweak this technique.

There might be some confusion on my wording but I hope you'll get it.

like image 190
Bhojendra Rauniyar Avatar answered Sep 30 '22 10:09

Bhojendra Rauniyar