Take an action on props change in ReactJS

I need to use current props and previous props value in my React component.
So i did it like this

state = {
    current: null,
    previous: null,
};

componentWillReceiveProps(nextProps) {
    if (nextProps.amount !== this.state.current) {
        this.setState({previous: this.state.current, current: nextProps.amount});
    }
}

...

render() {
    const {previous, current} = this.state;

    return (
        ...
        <CountUp className="counter" start={previous} end={current} duration={1}/>
        ...
    )
}

It works fine, but is it good React practise to do it like this? Are there others “good” ways to do it?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

As of v16.2.0, componentWillReceiveProps is the right place to update state, based on prop changes and since you want to use both current state and previous state in render, you need to maintain, two different state variables as you are doing

However, when you update the state based on previous state, use functional setState method

Check this answer for more details

When to use functional setState

componentWillReceiveProps(nextProps) {
    if (nextProps.amount !== this.state.current) {
        this.setState(prevState => ({ previous: prevState.current, current: nextProps.amount }));
    }
}

According to the latest RFC to React

State derived from props/state

The purpose of this pattern is to calculate some values derived from props for use during render.

Typically componentWillReceiveProps is used for this, although if the calculation is fast enough it could just be done in render.:

From v16.3.0 onwards, you would make use of

static getDerivedStateFromProps(nextProps, prevState) {
    if (
      !prevState ||
      prevState.current !== nextProps.amount
    ) {
      return {
        previous: prevState.current,
        current: nextProps.amount
      };
    }
}

Method 2

I’d like to update this answer for anyone else who comes here from Google. As of v16.8.6, componentWillReceiveProps has been marked as legacy, and is not recommended to use. Instead you should use componentDidUpdate and update your state based on the new props and previous props/previous state.

componentDidUpdate(prevProps, prevState) {
   if (this.props.someVal !== prevState.someVal) {
     this.setState({ previous: prevState.someVal, current: this.props.someVal });
   }
}

Obviously, whether you check the previous state or the previous props is up to your discretion/situation. You can implement componentDidUpdate with or without the parameters, but if you want prevState you must declare prevProps.

React Update Lifecycle

componentDidUpdate()

Method 3

You can use an arrow function in your setState object.
Like this :

this.setState((prevState) => {
      return { yourState: prevState.yourState }
    })

prevState is a default name but you can replace the name as you want


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x