usePrevious
Prompt
Create a custom React hook called usePrevious
that tracks the previous value of a state variable or prop.
This hook is useful for comparing previous and current values of props or state, such as when you need to perform side effects based on value changes.
Requirements
- The hook should accept any value as a parameter
- The hook should return the previous value of that parameter from the last render
Example
function CounterComponent() {
const [count, setCount] = useState(0);
const previousCount = usePrevious(count);
return (
<div>
<p>Current Count: {count}</p>
<p>Previous Count: {previousCount !== undefined ? previousCount : 'None'}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
Playground
You need to use useRef
to store the previous value between renders:
const ref = useRef();
Use the useEffect
hook to update the ref with the current value after each render:
useEffect(() => {
// Update the ref with the current value here
}, [value]);
Solution
Explanation
The usePrevious
hook is a custom hook that stores and returns the previous value of a variable between renders. Here's how it works:
First, we create a mutable ref using useRef
to store our previous value:
const ref = useRef();
Unlike state variables, refs don't trigger re-renders when they change, making them perfect for storing values that we need to persist between renders without causing additional rendering cycles.
Next, we use the useEffect
hook to update our ref after each render:
useEffect(() => {
ref.current = value;
});
Notice that we don't provide a dependency array to useEffect
. This means the effect will run after every render. When the component renders, the effect doesn't run until after the render is committed to the screen. This is key to how the hook works:
- During the first render, the ref is uninitialized, so
ref.current
isundefined
. - After rendering, the effect runs and updates
ref.current
to the current value. - On the next render,
ref.current
contains the value from the previous render, while the actual parameter contains the new current value.
Finally, we return the value stored in our ref:
return ref.current;
On the first render, this will be undefined
, but on subsequent renders, it will contain the value from the previous render.
This hook is particularly useful when you need to compare the current value with the previous value, such as for detecting changes in state or props, or when implementing effects that should only run when a specific value changes in a particular way.