With functional components now being the standard in React, we lost one notable perk of using the lifecycle hooks (such as componentDidUpdate()
) of class-based components: the intrinsic ability to compare previous values to new ones.
If I wanted to respond to a component's "count" change for example, I could do something like:
componentDidUpdate(prevProps, prevState) {
if (this.props.count > prevProps.count) {
// Count incremented! Do something.
}
}
I came across the need to do this while working on Emoji Battle yesterday—I wanted to show an animation anytime an emoji's vote count incremented.
Luckily Stack Overflow had a great solution as usual, which I turned into a hook I'll probably reuse in the future.
Basically you create a very simple custom hook that uses a React ref to track the previous value, and refer to it in the useEffect.
function usePreviousValue(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
Based on this, I used it to increment my Emoji counter as follows:
export const Count = ({ value }) => {
const controls = useAnimation();
const previousValue = usePreviousValue(value);
useEffect(() => {
if (!previousValue || value > previousValue) {
// Trigger the framer-motion animation
controls.start({
scale: [1, 1.5, 1],
transition: {
duration: 0.5,
},
});
}
}, [value]);
Try this usePreviousValue
hook out next time you need to track value changes in React functional components.
Top comments (0)