javascriptreactjsredux

replace componentWillRecieiveProps in react 16 in redux?


Says I have this reducer that changed my job status from 'pending' to 'approve',

how to use handle it without using the going to be deprecated componentWillRecieiveProps?

I used to do this

componentWillRecieiveProps(prevProps, nextProps) {
  if (prevProps.job.status !== nextProps.job.status && nextProps.job.state === 'approved') {
    this.props.history.replace('somewhere')
  }
}

Solution

  • @Shishir Anshuman's comment is correct you should use getDerivedStateFromProps, but it's not super obvious how, so I'm going to show you.

    This is your original snippet which compares prevProps with nextProps:

    componentWillRecieiveProps(prevProps, nextProps) {
      if (prevProps.job.status !== nextProps.job.status && nextProps.job.state === 'approved') {
        this.props.history.replace('somewhere')
      }
    }
    

    What it should look like is something like this:

    static getDerivedStateFromProps(nextProps, prevState) {
      if (prevState.job.status !== nextProps.job.status && nextProps.job.state === 'approved') {
        // return new object to update state
      }
      return null;
    }
    

    That's based on the assumption that you're storing job.status in local state, so your component's construction would need to look something like this:

    constructor(props) {
      super(props);
    
      this.state = {
        job: props.job,
      };
    }
    

    Although given I don't have full visibility of your data structure I would probably store the job.status in local state as boolean called jobStatus, then only interrogate this.props.job object in my render when this.state.jobStatus is true.

    If you do that then your getDerivedStateFromProps would look like this:

    static getDerivedStateFromProps(nextProps, prevState) {
      if (prevState.jobStatus !== nextProps.job.status && nextProps.job.state === 'approved') {
        // return new object to update state
      }
      return null;
    }
    

    Edit 1

    As @Patrick Hund pointed out in the comments I missed the static keyword before the getDerivedStateFromProps method, this is required.

    Edit 2

    As @markerikson correctly points out in the comment below getDerivedStateFromProps should be a pure function and have no side effects, I've updated the snippets to reflect this.

    This is the important sentence from the docs I didn't fully grok:

    It should return an object to update state, or null to indicate that 
    the new props do not require any state updates.