EasyHooks📖 Theory Question

What is useCallback and when does it actually help?

💡

Hint

Memoizes a function reference — only helps when the function is a dep of useEffect or a prop to React.memo children

Full Answer

useCallback(fn, deps) returns a memoized function that only changes if deps change.

const handleClick = useCallback(() => {
  doSomething(id);
}, [id]); // only creates a new function when id changes

It only helps in two scenarios:

1. Passed to a React.memo child (prevents unnecessary re-renders):

const MemoChild = React.memo(({ onClick }) => );

// Without useCallback — new function ref every render → MemoChild always re-renders
// With useCallback — same ref if deps unchanged → MemoChild skips re-render
const handleClick = useCallback(() => doWork(id), [id]);

2. Used as a useEffect dependency:

const fetchData = useCallback(() => {
  api.get(url).then(setData);
}, [url]);

useEffect(() => { fetchData(); }, [fetchData]); // won't re-run unless url changes

When it does NOT help:

  • Functions passed to native DOM elements (div, button) — they don't check reference equality
  • Without React.memo on the child — the child re-renders regardless
💡 useCallback has a cost — it runs on every render to check deps. Don't add it everywhere "just in case". Profile first, optimize second.

Practice this in a timed sprint →

5 free questions, no signup required

⚡ Start Sprint