0

I was using the componentWillReceiveProps lifecycle event to enable or disable transition to the next page. Now that this event is changed to UNSAFE_componentWillReceiveProps, I feel like I shouldn't use it anymore, however I couldn't find an obvious replacement for it.

The location of the component comes from props.location.pathname, so I'd need an event, where I can access both the previous and next props and then set the initial appearance of the component depending on if there should be transition or not, however:

  • getDerivedStateFromProps only has access to the previous props.
  • shouldComponentUpdate should be used for telling the component if it should update or not, which is not what we want, so it's out.
  • render doesn't have the previous props.
  • getSnapshotBeforeUpdate passes the parameter to componentDidUpdate, at which point the component is already rendered, so I can't set the initial apprearance.

I guess I could save the previous pathname and use that the next time in render, but this doesn't seem like an elegant solution. What is the best practice in this situation?

András Geiszl
  • 966
  • 2
  • 16
  • 36

3 Answers3

1

You can use below which is Safe and recommend by Reactjs

componentDidUpdate(prevProps) { 

     if (this.props.userID !== prevProps.userID) {

        this.fetchData(this.props.userID); 

    }
 }
pareshm
  • 4,874
  • 5
  • 35
  • 53
  • Wouldn't this re-render the component and cause flickering if the appearance of the page changes? I'm doing a full background transition here, so the whole page would update if didn't get the initial state right. – András Geiszl Sep 24 '18 at 16:19
  • Right complete component will get rerender so I don't think flickering will occur. – pareshm Sep 25 '18 at 08:54
1

You stated that

getDerivedStateFromProps only has access to the previous props.

But getDerivedStateFromProps has access to next props and previous state

Saving the previous pathname may not seem elegant, I agree, but it is an alternative offered here: https://codesandbox.io/s/rjyvp7l3rq found here https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html.

Take a look at the uncontrolledEmailInput component saving prev props in state

state = {
    email: this.props.defaultEmail,
    prevPropsUserID: this.props.userID
  };

  static getDerivedStateFromProps(props, state) {
    // Any time the current user changes,
    // Reset any parts of state that are tied to that user.
    // In this simple example, that's just the email.
    if (props.userID !== state.prevPropsUserID) {
      return {
        prevPropsUserID: props.userID,
        email: props.defaultEmail
      };
    }
    return null;
  }

Here is a great article about the new lifecycles: https://medium.com/@baphemot/understanding-react-react-16-3-component-life-cycle-23129bc7a705

Meeses
  • 144
  • 1
  • 1
  • 6
  • Thanks, I guess this is the best solution then. I still don't like it though as you'll have an additional state just for checking the previous path. – András Geiszl Sep 25 '18 at 08:02
  • Hi, How you could initiate a state with previous route path if in the constructor we already get the latest route path in `props.location.pathname`? – Akza Oct 06 '20 at 01:20
0

As per react documentation you should use componentDidUpdate. It has access to prevProps, prevState and current props, state in this.props, this.state.

Take a look at the documentation https://reactjs.org/docs/react-component.html#componentdidupdate

componentDidUpdate(prevProps) {
    if(this.props.pathname !== prevProps.pathname) {
      //do something here or setState to adjust the appearance accordingly
    }
}
Shubham Gupta
  • 2,596
  • 1
  • 8
  • 19
  • I'll ask you what I asked the other person, who had the same answer: "Wouldn't this re-render the component and cause flickering if the appearance of the page changes? I'm doing a full background transition here, so the whole page would update if didn't get the initial state right." – András Geiszl Sep 24 '18 at 16:59