Reputation: 283
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?
Upvotes: 5
Views: 13892
Reputation: 363
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
.
Upvotes: 6
Reputation: 282050
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 inrender
.:
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
};
}
}
Upvotes: 7
Reputation: 2187
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
Upvotes: 2