React useReducer Hook

React.js 119 views Nov 05, 2025 2 min read

The useReducer hook is an alternative to useState for managing complex state logic. It is especially useful when state updates depend on previous state or involve multiple related values.


Why useReducer?

Use useReducer when:

  • State logic is complex

  • Multiple state values are related

  • Many different actions update the state

  • You want predictable state transitions

It follows a pattern similar to Redux, but is built into React.


Basic Syntax

import { useReducer } from "react"; const [state, dispatch] = useReducer(reducer, initialState);
  • state → current state

  • dispatch → function to trigger actions

  • reducer → function that updates state

  • initialState → starting state


Reducer Function

A reducer takes the current state and an action, then returns the new state.

function reducer(state, action) { switch (action.type) { case "increment": return { count: state.count + 1 }; case "decrement": return { count: state.count - 1 }; default: return state; } }

Simple Counter Example

function Counter() { const initialState = { count: 0 }; const [state, dispatch] = useReducer(reducer, initialState); return ( <> <p>Count: {state.count}</p> <button onClick={() => dispatch({ type: "increment" })}> + </button> <button onClick={() => dispatch({ type: "decrement" })}> - </button> </> ); }

Actions

Actions are plain objects:

{ type: "increment" }

With payload:

{ type: "add", payload: 5 }

Reducer:

case "add": return { count: state.count + action.payload };

Lazy Initialization

const [state, dispatch] = useReducer( reducer, initialArg, initFunction );
  • Useful for expensive initial state calculations


useReducer vs useState

useReduceruseState
Complex logicSimple state
Centralized updatesDirect updates
Predictable transitionsQuick and simple
Redux-likeMinimal

Common Use Cases

  • Forms with multiple fields

  • Complex UI state

  • State transitions with rules

  • Managing global state with Context


Combining useReducer with useContext

const AppContext = createContext(); function AppProvider({ children }) { const [state, dispatch] = useReducer(reducer, initialState); return ( <AppContext.Provider value={{ state, dispatch }}> {children} </AppContext.Provider> ); }

Best Practices

  • Keep reducers pure

  • Do not mutate state

  • Use clear action types

  • Split large reducers


Key Points

  • useReducer manages complex state

  • Reducers define how state changes

  • Actions describe what happened

  • Ideal for predictable state logic

Some advanced sections are available for Registered Members
Share this Post
🚀 Want to Test Your Knowledge?

Take quizzes related to this topic and see where you stand!

Start Quiz Now
Back to Tutorials