React  

Which React 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

  • You have multiple related state values
  • State transitions are more complex (like with Redux-style actions)

🧠 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

  • You need a reference to a DOM element
  • You want to persist a value without triggering re-renders

🧠 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.

Founded in 2003, Mindcracker is the authority in custom software development and innovation. We put best practices into action. We deliver solutions based on consumer and industry analysis.