Abstract Once, Reuse Everywhere: Custom Hooks

Encapsulate stateful logic into reusable hooks like useAuth or useDebounce. This keeps components clean while promoting reuse. Avoid overengineering—use them when logic truly repeats.

Custom Hooks let you extract reusable, stateful logic from components into standalone functions.

👉 Think of them as mini-React components for logic — you keep your UI clean while sharing behavior across components.

Basics & Need

React provides built-in hooks like useState, useEffect, and useReducer. Often, multiple components need the same logic (e.g., fetching data, toggling a modal, debouncing input).

Instead of copying code, you extract it into a custom hook to reuse cleanly.

How to Achieve It

Example 1: Toggle Hook

function useToggle(initial = false) {
const [state, setState] = React.useState(initial);
const toggle = () => setState((s) => !s);
return [state, toggle];
}

// Usage
const ToggleButton = () => {
const [isOn, toggle] = useToggle();
return <button onClick={toggle}>{isOn ? "ON" : "OFF"}</button>;
};

Example 2: Fetch Hook

function useFetch(url) {
const [data, setData] = React.useState(null);
const [loading, setLoading] = React.useState(true);

React.useEffect(() => {
fetch(url)
.then((res) => res.json())
.then((json) => {
setData(json);
setLoading(false);
});
}, [url]);

return { data, loading };
}

// Usage
const UserList = () => {
const { data, loading } = useFetch("/api/users");
return loading ? <p>Loading...</p> : <ul>{data.map(u => <li>{u.name}</li>)}</ul>;
};

Best Practices

  • Name hooks with use prefix (useToggle, useFetch).
  • Keep them focused on one concern.
  • Avoid side effects outside hooks; keep effects inside useEffect.
  • Return only what’s needed — don’t expose internal state unnecessarily.

Real-World Examples

  1. Auth HookuseAuth() manages login state across components.
  2. Form HookuseForm() handles form state, validation, and submission.
  3. Window Size HookuseWindowSize() tracks browser resizing for responsive design.

Advantages

  • Promotes reusable logic without duplicating code.
  • Keeps components clean and focused on UI.
  • Easy to test hooks independently.
  • Combines nicely with Context API for global state.

Disadvantages

  • Can become hard to debug if too many hooks are nested.
  • Over-abstraction may make simple logic unnecessarily complex.
  • Hooks cannot be used conditionally — always call them in the same order.

Common Problems / Pitfalls

  • Violating Rules of Hooks (calling inside loops, conditions).
  • Overloading a hook with multiple concerns → hard to reuse.
  • Not memoizing functions inside hooks (useCallback) → causes unnecessary re-renders.

Summary Recommendation

Use Custom Hooks to extract reusable logic from components and simplify your UI. They are essential in modern React for managing state, effects, and side effects consistently. Keep them focused, testable, and clean — and your components will stay readable, maintainable, and scalable.