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:

🧠 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, and 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 the 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.