Fullstack CourseLearn by building

react · source-driven

Refs, custom Hooks, useMemo, useCallback

Escape hatches and performance Hooks: refs, custom Hooks, caching calculations with useMemo, and caching functions with useCallback.

You will learn

  • When to use a ref vs state
  • How to build a custom Hook that starts with use
  • When useMemo caches a calculation (and when to skip it)
  • When useCallback keeps a function identity stable

Refs (official: Referencing values with refs)

Read Referencing values with refs. Refs are for values that change but should not re-render — or for DOM access.

const inputRef = useRef(null);
// later: inputRef.current.focus();

Try it

Interval ticks (ref + state): 0

Custom Hooks

From the docs: extract reusable logic into a function whose name starts with use. It can call other Hooks.

function useToggle(initial = false) {
  const [on, setOn] = useState(initial);
  return { on, toggle: () => setOn(v => !v) };
}

Try it

useMemo (official: Caching a calculation)

Read useMemo. Cache expensive derived values; skip it for cheap work. Theme below is unrelated to the filter — changing it should not force a new memoized list when query is unchanged.

const visible = useMemo(
  () => tickets.filter(t => t.title.includes(query)),
  [tickets, query],
);

Try it

theme=light · matches=20 (memo deps: tickets, query)

useCallback (official: Caching a function)

Read useCallback. Same idea as useMemo(() => fn, deps) for functions — useful when a memoized child or Effect depends on reference equality.

const onStatusLog = useCallback(() => { ... }, [status]);
useEffect(() => { /* runs when onStatusLog identity changes */ }, [onStatusLog]);

Try it

renders=1 · Effect deps=[useCallback] runs=0

Recap

  • useRef for non-reactive values and DOM nodes
  • Custom Hooks share stateful logic
  • useMemo caches calculated values — derive first, memoize when needed
  • useCallback caches function identity for memoized children / Effect deps

Challenge

Try this

Filter a list with useMemo, then pass a stable onSelect via useCallback into a child wrapped in React.memo. Confirm the child does not re-render when an unrelated parent state flips.