0
0
ReactComparisonBeginner · 4 min read

UseReducer vs useState in React: Key Differences and When to Use Each

In React, useState is best for simple state updates and local component state, while useReducer is ideal for complex state logic or when multiple state values depend on each other. useReducer helps organize state changes with a reducer function, making it easier to manage and test.
⚖️

Quick Comparison

Here is a quick side-by-side comparison of useState and useReducer hooks in React.

FactoruseStateuseReducer
PurposeManage simple state valuesManage complex state logic
State UpdatesDirectly set new stateDispatch actions to reducer
State StructureUsually single value or simple objectCan handle complex nested state
Code ComplexityLess code for simple casesMore code but clearer for complex logic
When to UseLocal state, simple toggles, countersMultiple related state values, complex updates
TestingState updates inlineReducer function can be tested separately
⚖️

Key Differences

useState is a React hook that lets you add simple state to functional components. You call it with an initial value and get back the current state and a function to update it. It works well when your state is a single value or a simple object and updates are straightforward.

useReducer is another React hook that manages state using a reducer function. This function takes the current state and an action, then returns a new state. It is great when your state logic is complex, involves multiple sub-values, or when the next state depends on the previous state in complicated ways.

Unlike useState, which updates state directly, useReducer uses a dispatch method to send actions describing what happened. This makes your state changes more predictable and easier to debug or test because all changes go through the reducer function.

⚖️

Code Comparison

Here is how you would implement a simple counter using useState:

jsx
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={() => setCount(count - 1)}>Decrement</button>
    </div>
  );
}

export default Counter;
Output
A simple counter showing the current count and two buttons to increase or decrease it.
↔️

useReducer Equivalent

The same counter implemented with useReducer looks like this:

jsx
import React, { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error('Unhandled action type');
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
    </div>
  );
}

export default Counter;
Output
A simple counter showing the current count and two buttons to increase or decrease it.
🎯

When to Use Which

Choose useState when:

  • Your state is simple, like a number, string, or boolean.
  • You only need to update one or two values without complex logic.
  • You want quick and easy state management with minimal code.

Choose useReducer when:

  • Your state has multiple related values that change together.
  • You have complex update logic that depends on previous state.
  • You want to keep state update logic separate and testable.
  • You prefer a more predictable and organized way to handle state changes.

Key Takeaways

Use useState for simple, local state with straightforward updates.
Use useReducer for complex state logic involving multiple related values.
useReducer centralizes state updates in a reducer function, improving predictability and testability.
Choosing the right hook depends on state complexity and how you want to organize updates.
Both hooks are essential tools for managing state in React functional components.