Once you study React a bit, repeated patterns start showing up everywhere. The same useState, useEffect, and event handling logic appears in multiple components, and many people wonder whether the answer is “make another component.” If the repetition is in logic rather than UI, a custom hook is often the better fit.
Custom hooks can sound advanced, but the basic idea is simple: wrap related React hook logic inside a reusable function. Once that clicks, components become easier to read because they can focus more on UI and less on repeated wiring.
This post covers three things.
- when a custom hook is worth creating
- how a hook differs from a component
- practical examples that make good practice projects
The main takeaway is this: if the screens differ but the state behavior is the same, think about a custom hook before another component abstraction.
What a React custom hook is
A custom hook is a function whose name starts with use and which can call other React hooks internally. Its job is not to reuse UI. Its job is to reuse stateful logic and side-effect behavior.
For example, window resize tracking often repeats across many components.
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
function handleResize() {
setWidth(window.innerWidth);
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
Now any component can call const width = useWindowWidth(); and stay focused on rendering.
When a custom hook is a good idea
A custom hook is often worth it when:
- a
useStateanduseEffectpattern repeats across files - several screens share the same state transitions
- loading, error, or retry behavior keeps repeating
- one component has become hard to read because the logic is too long
If the repeated part includes JSX structure and visual output, a component may be the better answer. The distinction is simple: hooks reuse logic, components reuse UI.
How hooks and components differ
Components return rendered output. Hooks return values, functions, and behavior.
A good example is modal behavior.
Modal: draws the actual layer and markupuseModal: manages whether it is open and how it opens or closes
function useModal() {
const [open, setOpen] = useState(false);
return {
open,
openModal: () => setOpen(true),
closeModal: () => setOpen(false),
toggleModal: () => setOpen((prev) => !prev),
};
}
This lets different screens reuse the same modal behavior while keeping the rendered UI flexible.
Good practice hooks for beginners
It helps to start with small, concrete wins rather than trying to build a huge all-purpose hook.
Some good practice ideas are:
useToggleuseInputuseDebounceuseFetchPostsuseModal
These are great because they naturally combine state, effects, cleanup, and naming decisions in a manageable way.
Common mistakes
1. Making the hook too generic too early
A hook with too many options and branches can become harder to understand than the duplicated code it replaced.
2. Hiding UI concerns inside the hook
If the hook starts deciding button labels, markup structure, or styling classes, responsibilities are getting mixed.
3. Returning an unclear API
The return value is the public contract of the hook. If that contract is confusing, the callers will also be confusing.
A small example: debounced input
If you want to reduce how often a search query triggers requests, a debounce hook is a good practice case.
function useDebounce(value, delay = 300) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
}
This is a small hook, but it touches state, effect cleanup, and dependency handling all at once, which makes it an excellent learning project.
Questions to ask before extracting a hook
- Is the repeated thing UI or logic?
- Can I name this behavior clearly?
- What is the smallest useful API to return?
- Does the hook keep effect and cleanup responsibility contained?
- Is this hook trying to do too many jobs?
If the answers stay clear, the hook will make the codebase easier to understand instead of more abstract.
FAQ
Q. Can a custom hook call other hooks?
Yes. That is the normal pattern as long as React hook rules are followed.
Q. When should I move a hook into its own file?
If more than one component can use it, or if it makes the current file significantly easier to read, that is often enough reason.
Q. Can too many custom hooks make code harder to follow?
Yes. That is why naming and clear responsibility matter more than the number of hooks.
Read Next
- If dependency arrays and effect behavior still feel shaky, revisit React useEffect Guide.
- If you want to understand memoization and unnecessary re-renders next, continue with React Rendering Optimization Guide.
While AdSense review is pending, related guides are shown instead of ads.
Start Here
Continue with the core guides that pull steady search traffic.
- Middleware Troubleshooting Guide: Redis vs RabbitMQ vs Kafka A practical middleware troubleshooting guide for developers covering when to reach for Redis, RabbitMQ, or Kafka symptoms first, and which problem patterns usually belong to each tool.
- Kubernetes CrashLoopBackOff: What to Check First A practical Kubernetes CrashLoopBackOff troubleshooting guide covering startup failures, probe issues, config mistakes, and what to inspect first.
- Kafka Consumer Lag Increasing: Troubleshooting Guide A practical Kafka consumer lag troubleshooting guide covering what lag usually means, which consumer metrics to check first, and how poll timing, processing speed, and fetch patterns affect lag.
- Kafka Rebalancing Too Often: Common Causes and Fixes A practical Kafka troubleshooting guide covering why consumer groups rebalance too often, what poll timing and group protocol settings matter, and how to stop rebalances from interrupting useful work.
- Docker Container Keeps Restarting: What to Check First A practical Docker restart-loop troubleshooting guide covering exit codes, command failures, environment mistakes, health checks, and what to inspect first.
While AdSense review is pending, related guides are shown instead of ads.