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.
Official docs: react.dev — useMemo
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.