import { useCallback, useEffect, useRef, useState } from 'react'; /** * A message that shows itself and then goes away — "Saved", and whatever joins it. * * ── Why this is not a piece of state somebody sets and clears ── * * The timer is held in a ref and CLEARED before each new one is set. Without that, saving twice in * quick succession leaves the first timeout running, and it fires against the second save — the * confirmation vanishes a moment after appearing, which looks like the second save failed. * * The cleanup on unmount matters for the same reason it always does: this lives in a panel that is * swapped out whenever the nav moves, and a timeout that outlives its component sets state on nothing. */ export const useFlash = (ms = 5000) => { const [showing, setShowing] = useState(false); const timer = useRef | null>(null); const clear = () => { if (timer.current) clearTimeout(timer.current); timer.current = null; }; const flash = useCallback(() => { clear(); setShowing(true); timer.current = setTimeout(() => setShowing(false), ms); }, [ms]); useEffect(() => clear, []); return [showing, flash] as const; };