🧩 What Is Hook Composition?
Hook composition is the practice of building a custom Hook by combining multiple React Hooks or even other custom Hooks. Instead of placing all logic into a single large Hook, you compose several smaller Hooks together, each handling one responsibility. This makes your code modular, reusable, and easier to maintain.
Important
🎯 Why Compose Multiple Hooks?
As applications become more complex, a single custom Hook may need to manage state, perform side effects, access browser APIs, and share context. Rather than implementing everything in one place, multiple Hooks can work together to create a clean abstraction.
- Keep each Hook focused on one responsibility.
- Reuse existing Hooks instead of rewriting logic.
- Create more powerful custom Hooks.
- Improve readability and maintainability.
🔄 How Hook Composition Works
💻 Example 1: Two Independent Hooks
Creating Small Hooks
import { useState, useEffect } from "react";
function useCounter() {
const [count, setCount] = useState(0);
function increment() {
setCount(c => c + 1);
}
return { count, increment };
}
function useDocumentTitle(title) {
useEffect(() => {
document.title = title;
}, [title]);
}Each Hook has a single responsibility. One manages counter state, while the other updates the document title.
💻 Example 2: Composing the Hooks
Creating a Composed Hook
function useCounterWithTitle() {
const {
count,
increment
} = useCounter();
useDocumentTitle(
`Count: ${count}`
);
return {
count,
increment
};
}The new Hook combines the behavior of two existing Hooks without duplicating their implementation.
💻 Example 3: Using the Composed Hook
Using useCounterWithTitle
function Counter() {
const {
count,
increment
} = useCounterWithTitle();
return (
<>
<h2>{count}</h2>
<button onClick={increment}>
Increment
</button>
</>
);
}The component automatically receives both counter functionality and dynamic document title updates through a single custom Hook.
💻 Example 4: Combining Multiple Browser Hooks
Composing Browser Logic
function useDashboard() {
const isOnline = useOnlineStatus();
const width = useWindowSize();
const theme = useTheme();
return {
isOnline,
width,
theme
};
}Instead of calling three separate Hooks in every component, a single composed Hook exposes all related information together.
📊 Small Hooks vs Large Hooks
| Small Focused Hooks | One Large Hook |
|---|---|
| Single responsibility. | Handles multiple unrelated concerns. |
| Easy to test. | More difficult to test. |
| Highly reusable. | Often tightly coupled. |
| Easy to compose. | Harder to maintain. |
📅 Composition Process
Create small Hooks that solve individual problems.
Call multiple Hooks inside a new custom Hook.
Combine and return the required values.
Reuse the composed Hook throughout the application.
Extend functionality by composing additional Hooks when needed.
🎯 Common Use Cases
Combine Hooks for themes, user preferences, network status, and window size into a single dashboard Hook.
Compose validation, input management, and submission Hooks into a reusable form Hook.
Combine authentication, permissions, and user profile Hooks into one authentication Hook.
Merge data fetching, caching, loading, and error handling Hooks into a unified data Hook.
⚠️ Common Mistakes
- Creating one massive Hook instead of composing smaller Hooks.
- Combining unrelated responsibilities into a single Hook.
- Duplicating logic instead of reusing existing Hooks.
- Violating the Rules of Hooks when composing multiple Hooks.
Warning
✅ Best Practices
- Design small Hooks with a single responsibility.
- Compose Hooks instead of copying logic.
- Return a simple, well-defined API from composed Hooks.
- Reuse existing Hooks whenever possible.
- Keep rendering logic inside components and business logic inside custom Hooks.
📚 Official Resource
Learn more about composing custom Hooks in the official React documentation at Reusing Logic with Custom Hooks.