Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 683
Mad Max Avatar asked Feb 28 '18 09:02

Mad Max


People also ask

Do something when props change React?

To update state when props change in React: Pass the props as dependencies to the useEffect hook. Every time the props change, the logic in useEffect is reran.

How do you call a function when props change?

useEffect(()=>{ console. log('something prop has changed. ') },[props. something]);

Is componentDidMount called when props change?

Conclusion. By default, a React component will only call componentDidMount once. The only way it will get run again is if you delete the component or change the key prop value.


1 Answers

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
      };
    }
}
like image 58
Shubham Khatri Avatar answered Nov 15 '22 02:11

Shubham Khatri