All topics
Patternsintermediate

Custom Hook Composition (Hooks Calling Hooks)

Learn how custom hooks can call other custom hooks to build layered, composable abstractions for complex behavior.

Just as components compose by rendering other components, custom hooks compose by calling other hooks — built-in or custom — inside their own body. A hook like useAuthenticatedFetch(url) might internally call a lower-level useAuth() hook to get the current token and a useFetch(url, options) hook to perform the actual request, combining them into one higher-level piece of reusable behavior.

Composed hooks are like stacking simple electrical adapters to build exactly the plug you need for a specific outlet — each individual adapter (a small hook) does one clear job, and combining a few of them (a higher-level hook) solves a more specific, real-world need without any single adapter having to handle every possible scenario itself.

Key Concepts

1
This layering lets teams build a small internal 'hooks library' where simple, focused hooks (useDebounce, useLocalStorage, useAuth) serve as building blocks that more specific, feature-level hooks compose together, rather than every feature reimplementing debouncing or auth-token logic from scratch. Each layer stays testable and understandable in isolation, while higher layers assemble them into exactly the behavior a specific component needs.
useDebounceuseLocalStorageuseAuth
2
Because hook composition is just function composition under React's rules, all the same Rules of Hooks apply transitively — a custom hook that calls other hooks must still call them unconditionally at its own top level, and any component using the composed hook is really, transitively, using every hook in the chain underneath it.
3
Interviewers sometimes ask candidates to design a layered hook (like a usePaginatedQuery built from a lower-level useQuery and a usePagination hook) to assess whether they can decompose a complex requirement into smaller, individually reusable hooks rather than writing one large, monolithic custom hook that does everything inline.
usePaginatedQueryuseQueryusePagination