What is useReducer?

useReducer is like useState, but it’s better when:

  • State has multiple sub-values
  • You want to centralize logic (like in Redux)
  • You need predictable state updates

✅ Syntax

const [state, dispatch] = useReducer(reducer, initialState);

reducer = a function that receives current state + action → returns new state

dispatch(action) = used to trigger state updates

🧪 Simple Counter Example with useReducer

import React, { useReducer } from "react";

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

// Step 2: Initial state
const initialState = { count: 0 };

function Counter() {
  // Step 3: useReducer
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div style={{ padding: "20px" }}>
      <h2>Count: {state.count}</h2>
      <button onClick={() => dispatch({ type: "increment" })}>+1</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-1</button>
      <button onClick={() => dispatch({ type: "reset" })}>Reset</button>
    </div>
  );
}

export default Counter;

🧠 Why Use useReducer Over useState?

ScenariouseStateuseReducer
Simple toggle
Counter
Form with multiple fields👎 messy✅ better
Centralized logic
Multiple conditions or steps

🛠 You Can Use Objects or Strings for Action

Example:

dispatch({ type: "increment" }); // object
dispatch("increment"); // possible with custom reducer

Multi-field form using useReducer

import React, { useReducer } from "react";

// Step 1: Initial form state
const initialState = {
  name: "",
  email: "",
  age: "",
};

// Step 2: Reducer function
function formReducer(state, action) {
  switch (action.type) {
    case "UPDATE_FIELD":
      return {
        ...state,
        [action.field]: action.value,
      };
    case "RESET":
      return initialState;
    default:
      return state;
  }
}

function FormWithReducer() {
  // Step 3: Setup useReducer
  const [formState, dispatch] = useReducer(formReducer, initialState);

  // Step 4: Handle input change
  const handleChange = (e) => {
    const { name, value } = e.target;
    dispatch({
      type: "UPDATE_FIELD",
      field: name,
      value: value,
    });
  };

  // Step 5: Handle submit
  const handleSubmit = (e) => {
    e.preventDefault();
    console.log("Form submitted:", formState);
    alert("Check console for submitted data.");
  };

  return (
    <div style={{ padding: "20px" }}>
      <h2>Form using useReducer</h2>
      <form onSubmit={handleSubmit}>
        <div>
          <label>Name: </label>
          <input
            name="name"
            value={formState.name}
            onChange={handleChange}
            required
          />
        </div>

        <div>
          <label>Email: </label>
          <input
            name="email"
            value={formState.email}
            onChange={handleChange}
            required
          />
        </div>

        <div>
          <label>Age: </label>
          <input
            name="age"
            type="number"
            value={formState.age}
            onChange={handleChange}
          />
        </div>

        <br />

        <button type="submit">Submit</button>
        <button type="button" onClick={() => dispatch({ type: "RESET" })}>
          Reset
        </button>
      </form>
    </div>
  );
}

export default FormWithReducer;

Keep Learning 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *