🪝 React Hooks Explained: Which Hook to Use and When (With Examples)
React hooks simplify the way we manage state, side effects, and logic in functional components. But with so many hooks—useState
, useEffect
, useRef
, and more—developers often ask: "Which hook should I use, and when?"
This guide explains the most commonly used hooks in React, when to use them, and how they work — all with clear examples. Let's dive in! 🚀
1️⃣ useState
– For Simple Local State
✅ Use When:
You need to manage simple local state like numbers, strings, booleans, arrays, or objects.
🧠 Example:
const [count, setCount] = useState(0);
📝 Use case: Counter, form inputs, toggles.
2️⃣ useReducer
– For Complex State Logic
✅ Use When:
🧠 Example:
const [state, dispatch] = useReducer(reducer, initialState);
📝 Use case: Forms with validations, shopping carts, toggles with logic.
3️⃣ useEffect
– For Side Effects
✅ Use When:
You need to perform actions after render, such as:
-
Fetching data
-
Subscribing to events
-
Changing the DOM
🧠 Example:
useEffect(() => { fetchData(); }, []);
📝 Use case: API calls, event listeners, local storage access.
4️⃣ useRef
– For DOM Access and Persistent Variables
✅ Use When:
🧠 Example:
const inputRef = useRef(null);
📝 Use case: Managing focus, storing previous values, measuring DOM nodes.
5️⃣ useMemo
– For Expensive Computations
✅ Use When:
You want to memoize a computed value so it's not recalculated unnecessarily on every render.
🧠 Example:
const total = useMemo(() => computeTotal(items), [items]);
📝 Use case: Filtering large lists, heavy calculations.
6️⃣ useCallback
– For Memoized Functions
✅ Use When:
You want to prevent functions from being recreated unless dependencies change — especially when passing functions to child components.
🧠 Example:
const handleClick = useCallback(() => { doSomething(); }, []);
📝 Use case: Avoid unnecessary re-renders in child components.
7️⃣ useContext
– For Global or Shared State
✅ Use When:
You want to share data globally (like theme, language, user auth) without prop drilling.
🧠 Example:
const theme = useContext(ThemeContext);
📝 Use case: Authentication state, themes, localization.
8️⃣ useLayoutEffect
– For Layout Changes Before Paint
✅ Use When:
You need to read layout and re-render before the browser paints.
🧠 Example:
useLayoutEffect(() => { const height = ref.current.clientHeight; }, []);
📝 Use case: Measuring DOM, animations, positioning.
9️⃣ useImperativeHandle
– For Exposing Custom Functions via Ref
✅ Use When:
You want to expose imperative methods from a child component to its parent using ref
.
🧠 Example:
useImperativeHandle(ref, () => ({ focus: () => inputRef.current.focus() }));
📝 Use case: Exposing .open()
, .focus()
methods from a custom modal or input.
🔟 Custom Hooks – For Reusable Logic
✅ Use When:
You want to extract reusable logic across multiple components.
🧠 Example:
function useAuth() { const [user, setUser] = useState(null); return { user, login, logout }; }
📝 Use case: useAuth
, useForm
, useFetch
, useTheme
.
📌 Final Cheat Sheet
Purpose |
Hook |
Simple state |
useState |
Complex/multiple state |
useReducer |
Side effects (API, subscriptions) |
useEffect |
DOM access or persistent ref |
useRef |
Memoized value |
useMemo |
Memoized function |
useCallback |
Global/shared state |
useContext |
DOM layout measurement |
useLayoutEffect |
Expose functions via ref |
useImperativeHandle |
Reusable custom logic |
Custom Hook |
✅ Conclusion
React hooks are powerful, but choosing the right hook at the right time makes all the difference in writing clean, maintainable code.
Whether you're building a simple to-do app or a complex dashboard, this guide helps you choose wisely.