Hint
usePrevious reads ref.current before updating it — so it always holds the value from one render ago. Refs update synchronously during render, not after.
// Simulates usePrevious hook
function usePrevious(getValue) {
let ref = { current: undefined };
return function render(newVal) {
const prev = ref.current;
ref.current = newVal;
return { current: newVal, previous: prev };
};
}
const track = usePrevious();
const r1 = track(10);
const r2 = track(20);
const r3 = track(20);
console.log(r1.previous);
console.log(r2.previous);
console.log(r3.previous);
console.log(r3.current);undefined 10 20 20
Explanation: First render: previous is undefined (initial ref). Second: previous is 10. Third: previous is 20 (the previous render's value). Current is always the latest.
Key Insight: usePrevious reads ref.current before updating it — so it always holds the value from one render ago. Refs update synchronously during render, not after.