♻️ Reusing Logic in React
One of the greatest strengths of React is the ability to reuse logic instead of duplicating it across components. As applications grow, multiple components often require the same state management, side effects, or event handling. Custom Hooks provide a clean and reusable way to share this logic while keeping components focused on rendering.
Important
🎯 Why Reuse Logic?
Duplicating the same logic across multiple components increases maintenance costs and makes applications harder to understand. By extracting common behavior into a custom Hook, you can write the logic once and reuse it anywhere.
- Reduce duplicated code.
- Keep components clean and focused.
- Simplify maintenance and bug fixes.
- Encourage modular and reusable application design.
🔄 How Logic Reuse Works
💻 Example 1: Duplicated Logic
Without a Custom Hook
function CounterA() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}
function CounterB() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}Both components contain the same logic, resulting in unnecessary duplication.
💻 Example 2: Extracting the Logic
Creating useCounter
import { useState } from "react";
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
function increment() {
setCount(current => current + 1);
}
return {
count,
increment
};
}The counter logic now exists in one reusable location.
💻 Example 3: Reusing the Hook
Multiple Components Using the Same Hook
function CounterA() {
const { count, increment } = useCounter();
return (
<button onClick={increment}>
{count}
</button>
);
}
function CounterB() {
const { count, increment } = useCounter(10);
return (
<button onClick={increment}>
{count}
</button>
);
}Although both components share the same logic, each one has its own independent counter state.
💻 Example 4: Reusing Browser API Logic
useOnlineStatus
import {
useState,
useEffect
} from "react";
function useOnlineStatus() {
const [isOnline, setIsOnline] = useState(
navigator.onLine
);
useEffect(() => {
function updateStatus() {
setIsOnline(navigator.onLine);
}
window.addEventListener("online", updateStatus);
window.addEventListener("offline", updateStatus);
return () => {
window.removeEventListener("online", updateStatus);
window.removeEventListener("offline", updateStatus);
};
}, []);
return isOnline;
}Any component can now determine the browser's connection status by calling useOnlineStatus().
📊 Copying Code vs Reusing Logic
| Copying Logic | Custom Hooks |
|---|---|
| Code is duplicated. | Logic is written once. |
| Changes require multiple updates. | Changes happen in one place. |
| Harder to maintain. | Easier to maintain. |
| Larger components. | Smaller, focused components. |
📅 Logic Reuse Lifecycle
Repeated logic is identified across components.
The shared logic is extracted into a custom Hook.
Components call the custom Hook during rendering.
Each component receives its own independent Hook state.
The same logic is reused throughout the application.
🎯 Common Use Cases
Reuse API requests, loading states, and error handling across multiple components.
Share form validation, input management, and submission logic.
Wrap browser features such as window size, online status, geolocation, and local storage.
Reuse login, logout, session management, and user information throughout an application.
⚠️ Common Mistakes
- Copying code instead of extracting reusable logic.
- Expecting multiple components to share the same state automatically.
- Creating very large custom Hooks with multiple unrelated responsibilities.
- Returning unnecessary values from a custom Hook.
Warning
✅ Best Practices
- Extract logic only when it is reused or logically grouped.
- Keep custom Hooks focused on a single responsibility.
- Return a minimal and well-defined API.
- Compose several small Hooks instead of creating one large Hook.
- Keep rendering logic inside components and business logic inside Hooks.
📚 Official Resource
Learn more about reusing logic with custom Hooks in the official React documentation at Reusing Logic with Custom Hooks.