useUpdateEffectLoading saved progress…

useUpdateEffect

useEffect runs after the first render and after every update. But plenty of effects only make sense on changes — refetching when a filter changes, saving a draft when it edits, reacting to a prop that moved — and firing them on mount duplicates work you already did during initial render, or worse, triggers a spurious network call or toast the instant the component appears. useUpdateEffect is useEffect with the mount run skipped: it fires only on subsequent dependency changes.

Implement useUpdateEffect(effect, deps). Same signature as useEffect. Skip the very first run; on every later run caused by a dependency change, invoke effect and honor any cleanup function it returns.

Signature

function useUpdateEffect(effect, deps) {
  // like useEffect, but does NOT run on mount
}

Examples

useUpdateEffect(() => {
  refetch(query);        // runs when `query` changes, NOT on mount
}, [query]);
useUpdateEffect(() => {
  const id = setInterval(tick, delay);
  return () => clearInterval(id); // cleanup honored, just like useEffect
}, [delay]);

Notes

  • Skip the mount run — track "have we mounted yet?" in a ref; on the first effect run, flip it and return without calling effect.
  • Fire on every later change — after the first run is skipped, behave exactly like useEffect for all subsequent dependency changes.
  • Honor cleanup — return whatever effect returns so React can clean up before the next run and on unmount.
  • No cleanup from the skipped mount — since the effect never ran on mount, there's nothing to clean up from it.
Loading editor…