usePrevious

Comparing a value with what it was on the previous render is a recurring need: animating only when a number really changed, logging transitions, firing a request when an id moves on. A ref plus an Effect gives you that in six lines, because the Effect runs after the browser has painted: during a render the ref still holds the value the Effect stored last time.

A value that lags one render behindJavaScript
import { useRef, useEffect } from 'react';
export function usePrevious(value) {
  const ref = useRef(undefined);
  useEffect(() => { ref.current = value; });   // no dependency array: after every render
  return ref.current;
}

A counter rendering now: {count}, before: {String(previous)} therefore shows 4 and 3 after the fourth click. Writing to a ref schedules no render, so the Hook costs nothing extra; on the first render it returns undefined, which is why the component prints String(previous) rather than assuming a number.

The pattern works for props, state or any computed value, with one trap: it updates once per render, not once per change, so a re-render caused by something else leaves previous equal to value. When what you actually want is "reset state when a prop changes", prefer Lifting State and Keys's technique — a key on the child, or a comparison held in state — which stays correct under concurrent rendering.