Custom Hooks: Reuse Logic the React Way
Jun 11, 2026 · 8 min read
When two components need the same stateful logic, copying it around gets messy fast. A custom hook is React's built-in way to extract and reuse that logic — no new library, no special API.
A custom hook is just a function
It's a function whose name starts with use and that calls other hooks. Here's one that tracks a value in localStorage:
function useLocalStorage(key, initial) {
const [value, setValue] = useState(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initial;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}Now any component can use it like a built-in hook:
function Settings() {
const [theme, setTheme] = useLocalStorage('theme', 'light');
return <button onClick={() => setTheme('dark')}>{theme}</button>;
}Hooks share logic, not state
A common misconception: two components using the same custom hook do not share state. Each call gets its own independent state. The hook shares the behaviour, not the data. If you need shared data, lift it up or use context.
Follow the rules of hooks
- Only call hooks at the top level — never inside loops, conditions, or nested functions.
- Only call hooks from React components or other hooks.
- Start the name with
useso the linter can check those rules.
When to extract one
Extract a hook when you notice the same useState + useEffect pattern in more than one place, or when a component's logic is large enough that naming a piece of it improves readability — for example useFetch, useDebounce, or useMediaQuery.
Key takeaways
- A custom hook is a
use-prefixed function that calls other hooks. - It reuses logic; each component still gets its own state.
- Follow the rules of hooks so React can track them correctly.
Want the structured path? Explore the React roadmap or browse more articles.