NextProps in React Functional Components
Back in the day, when I was young (LOL), we use react 15, it was more verbose, convoluted, and lacking today's marvelous upgrades, but even when we have some live cycles you really know when to use each of them, besides the most important one "componentDidMount", there was another really important cycle to track props values "componentWillReceiveProps".
Back then you were able to compare the new props values against the current props values like
componentWillReceiveProps(nextProps) {
if(nextProps.count !== this.props.count) {
// Do something here since count prop has a new value
}
}
So let's say you need to do something like this in React 17 today, to skip an apollo query or to avoid any kinda side effects inside your components?
The first thing that may cross your mind is to set some states inside your component to track the props values using a useEffect hook:
function ComponentGettingProps({count, ...restProps}) {
const [localCount, setLocalCount] = React.useState(0)
React.useEffect(() => {
if(count === localCount) {
// count prop has the same value
setLocalCount(count)
// ... do what ever you need to do if the count prop value is the same
} else {
// count has a new value, update the local state
setLocalCount(count)
}
}, [count])
return (...)
}
Although this works, it may get pretty dirty in with the time since you may be checking several props and the logic block may get hard to read.
So, is there any other solution for the case? The answer is yes! Looky for us we can create a custom hook using one of the greatest react native hooks out there: "useRef()"
Let's build our custom hook "usePrevPropValue"
function usePrevPropValue(value) {
const ref = React.useRef();
React.useEffect(() => {
ref.current = value;
});
return ref.current;
}
Magically these hooks will return the previous count value in every re-render, the reason why this happens is that the stored value of current in ref get saved but not re-computed in every render, therefore the value you are returning is the previously stored one instead of the current prop value :), pretty super amazing, this is a vivid example that the lack of reactivity is also great.
Now let's use our hook
function ComponentGettingProps({count, ...restProps}) {
const prevCount = usePrevPropValue(count)
return (
<div>
New: {count} Prev: {prevCount}
</div>
);
}
Please notice that in practice we just get rid of defining a new state here, but in real life, we also get rid of re-render this component when updating the state we are not using any more :)
This is the live example in case you need the whole picture
https://codesandbox.io/s/naughty-snow-uoo48?file=/src/App.js
I hope this article helps you in your next project and thanks for reading. See ya in the next one!
Top comments (3)
Back in the day when I was young XD XD XD hahahhahah
Yeah man, way back! LOL
:)