Build a declarative wrapper around setTimeout for React. Raw setTimeout is imperative and fights React's render model — you set it up, tear it down, and its callback quietly goes stale as the component re-renders. useTimeout(callback, delay) hides all of that: it runs callback exactly once after delay milliseconds, always calls the latest version of the callback, does nothing when delay is null, and cleans itself up on unmount. It is the one-shot sibling of the classic useInterval.
function useTimeout(callback: () => void, delay: number | null): void;
Passing delay = null cancels the timeout so it never fires. The hook returns nothing.
function Toast({ message }) {
const [visible, setVisible] = useState(true);
// Auto-dismiss after 3 seconds. Pass null to keep it on screen forever.
useTimeout(() => setVisible(false), visible ? 3000 : null);
return visible ? <div className="toast">{message}</div> : null;
}
// Fires the LATEST callback exactly once, then stops.
// delay = 500: (wait 500ms) … fire once … done
// delay = null: (never fires — cancelled)
// changing delay 500 -> 800 before it fires: restart, fire once at 800ms
useInterval, a single setTimeout runs the callback one time after the delay and then never again.null means cancelled. A numeric delay schedules the timeout; null skips scheduling entirely. Flipping a pending timeout to null cancels it before it fires.500 to 800 before it fires should cancel the old timer and start a fresh one at the new delay.