DEV Community

Cover image for useReducer or Redux Reducer? How to Tell Which You Need
Bishoy Bishai
Bishoy Bishai

Posted on • Originally published at bishoy-bishai.github.io

useReducer or Redux Reducer? How to Tell Which You Need

Today, we have React, and life is beautiful. But then you hit a wall. Your useState hooks are multiplying like rabbits. Your component looks like a messy recipe where you forgot if you added salt or sugar. You hear about useReducer and Redux. You get confused.

Trust me, itโ€™s not that hard. Itโ€™s like choosing between a small tactical change during a football match or changing the entire club's formation.


Why Does State Get Messy?

Actually, state management is exactly like cooking.

  • useState is like making a fried egg. Simple. One ingredient, one pan, 2 minutes.
  • useReducer is like making a proper Egyptian Mahshi or a complex Lasagna. You have many steps, many ingredients, and if you don't follow a specific order (the "reducer"), the whole thing tastes like not good.
  • Redux is like running a professional Michelin-star restaurant kitchen. You have a Head Chef (the Store), specialized stations (Slices), and a strict way of passing orders (Actions).

If you try to run a whole restaurant using only one frying pan (useState), you will burn the kitchen down. But if you hire 10 chefs just to fry one egg, you are wasting money and time (over-engineering).


Understanding useReducer

In dancing, everything follows a rhythm. **1, 2, 3, Tap! If you don't hit the "Tap" on the 4th beat, you lose the flow. useReducer is exactly like this. It gives your state a rhythm.

Basically, useReducer is for local complexity. Imagine you have a video player component. You have "Play," "Pause," "Stop," "Volume Up," and "Mute." If you use useState for all of these, your code becomes a "Cramp."

With useReducer, you have one "Dance Lead" (the Reducer) who knows exactly what the next move is based on the beat (the Action).

The "Tactical" Reducer

Let's look at a real-world example of a complex form. Look my friend, don't do 10 useState hooks. Do this:

import React, { useReducer } from 'react';

// 1.  (State)
interface FormState {
  username: string;
  email: string;
  isSubmitting: boolean;
  errors: string[];
}

// 2. (Actions)
type FormAction =
  | { type: 'INPUT_CHANGE'; field: string; value: string }
  | { type: 'START_SUBMIT' }
  | { type: 'SET_ERRORS'; payload: string[] };

// 3. (The Reducer)
function formReducer(state: FormState, action: FormAction): FormState {
  switch (action.type) {
    case 'INPUT_CHANGE':
      // Like a perfect transition from defense to attack
      return { ...state, [action.field]: action.value };
    case 'START_SUBMIT':
      return { ...state, isSubmitting: true, errors: [] };
    case 'SET_ERRORS':
      return { ...state, isSubmitting: false, errors: action.payload };
    default:
      return state;
  }
}

// 4. (Component)
export const SignupForm = () => {
  const [state, dispatch] = useReducer(formReducer, {
    username: '',
    email: '',
    isSubmitting: false,
    errors: [],
  });

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    dispatch({ 
      type: 'INPUT_CHANGE', 
      field: e.target.name, 
      value: e.target.value 
    });
  };

  return (
    <form>
      <input name="username" onChange={handleChange} />
      {state.isSubmitting && <p>Loading the stadium...</p>}
    </form>
  );
};

Enter fullscreen mode Exit fullscreen mode

Why this works:

  1. Centralized Logic: All the "rules" of the form are in one function. It's like a coach's playbook.
  2. Predictability: You can't change the state by accident. You MUST send a dispatch (an Action).
  3. No Red Cards: It prevents "Impossible States" (like being isSubmitting: true while also having errors from the previous try).

๐ŸŸ๏ธ Redux: The Champions League of State

Now, Redux is a different beast. If useReducer is a tactical change for one player, Redux is the entire club's management system.

Trust me, many people hate Redux because they used the old version. But Redux Toolkit (RTK) is like modern football with VAR and high-tech scoutingโ€”itโ€™s much smoother.

โš”๏ธ Comparison Table: Picking Your Team

Feature useReducer Redux (RTK)
Setup Fast (No extra libraries) Needs a Store & Providers
Scope Local (One component/Feature) Global (Whole App)
Debugging Manual console.log Redux DevTools (Magic!)
Learning Curve Easy (It's just JS) Medium (Need to learn Slices/Actions)
Performance Can cause "Prop Drilling" Optimized with Selectors

Code Deep Dive: Redux Toolkit (The Modern Way)

Look how clean this is. It's like a well-organized kitchen prep station.

import { createSlice, PayloadAction } from '@reduxjs/toolkit';

// The "Ingredients"
interface PlayerState {
  name: string;
  goals: number;
}

const initialState: PlayerState = { name: 'Bishoy', goals: 0 };

// The "Cooking Station"
const playerSlice = createSlice({
  name: 'player',
  initialState,
  reducers: {
    // RTK uses "Immer" under the hood. 
    // You can write "mutating" code, but it's actually safe!
    scoreGoal: (state) => {
      state.goals += 1; 
    },
    setName: (state, action: PayloadAction<string>) => {
      state.name = action.payload;
    }
  }
});

export const { scoreGoal, setName } = playerSlice.actions;
export default playerSlice.reducer;

Enter fullscreen mode Exit fullscreen mode

Common Mistake: Many juniors try to put everything in Redux. Don't put "Is this dropdown open?" in Redux. That's like calling the Club President to ask if you can open a window. Keep UI state local!


Which one do you need?

  1. If your state is just for one page or one complex component (like a form or a table with filters) โ†’ useReducer.
  2. If your state is shared by different parts of the app (Auth, Theme, Shopping Cart) โ†’ Redux.
  3. If you need to persist data to LocalStorage or need DevTools to see what happened 5 minutes ago โ†’ Redux.

Basically, don't over-engineer. Don't bring a bus to carry one person, but don't try to fit 50 people in a Vespa.


๐Ÿ’ก Pro Tip

"Don't be afraid to mix!" Actually, the best apps use both. Use Redux for the "big picture" (Global state) and useReducer for the "local tactics" (Component state). Itโ€™s like having a great Manager in the office and a great Captain on the pitch. They work together to win the trophy!


โœจ Let's keep the conversation going!

If you found this interesting, I'd love for you to check out more of my work or just drop in to say hello.

โœ๏ธ Read more on my blog: bishoy-bishai.github.io

โ˜• Let's chat on LinkedIn: linkedin.com/in/bishoybishai

๐Ÿ“˜ Curious about AI?: You can also check out my book: Surrounded by AI


Top comments (0)