DEV Community

Cover image for Using useReducer for Complex State Logic
Reme Le Hane
Reme Le Hane

Posted on • Originally published at open.substack.com

Using useReducer for Complex State Logic

Skill: Manage Complex State with useReducer

Instead of juggling multiple useState calls, you can use useReducer to handle state transitions in a more structured way, similar to how Redux works.

When to Use useReducer

  • When your state has multiple interdependent variables (e.g., a form or a complex UI).

  • When your state transitions are complex and involve multiple actions.

  • When you want a cleaner and more scalable state management solution.

Example: Managing a Complex Form

Let’s use useReducer to handle the state of a form with multiple fields and actions:

import React, { useReducer } from "react";

// Define initial state
const initialState = {
  username: "",
  email: "",
  password: "",
  isSubmitting: false,
  error: null,
};

// Define a reducer function
const formReducer = (state, action) => {
  switch (action.type) {
    case "SET_FIELD":
      return { ...state, [action.field]: action.value };
    case "SUBMIT_START":
      return { ...state, isSubmitting: true, error: null };
    case "SUBMIT_SUCCESS":
      return { ...initialState }; // Reset form on success
    case "SUBMIT_ERROR":
      return { ...state, isSubmitting: false, error: action.error };
    default:
      throw new Error(`Unknown action type: ${action.type}`);
  }
};

const ComplexForm = () => {
  // Use useReducer to manage form state
  const [state, dispatch] = useReducer(formReducer, initialState);

  const handleChange = (e) => {
    const { name, value } = e.target;
    dispatch({ type: "SET_FIELD", field: name, value });
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    dispatch({ type: "SUBMIT_START" });

    try {
      // Simulate form submission
      await new Promise((resolve) => setTimeout(resolve, 1000));
      console.log("Form submitted:", state);
      dispatch({ type: "SUBMIT_SUCCESS" });
    } catch (error) {
      dispatch({ type: "SUBMIT_ERROR", error: "Submission failed!" });
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>Username:</label>
        <input
          name="username"
          value={state.username}
          onChange={handleChange}
        />
      </div>

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

      <div>
        <label>Password:</label>
        <input
          name="password"
          type="password"
          value={state.password}
          onChange={handleChange}
        />
      </div>

      {state.error && <p style={{ color: "red" }}>{state.error}</p>}

      <button type="submit" disabled={state.isSubmitting}>
        {state.isSubmitting ? "Submitting..." : "Submit"}
      </button>
    </form>
  );
};

export default ComplexForm;
Enter fullscreen mode Exit fullscreen mode

How It Works

  1. State Centralization:
  • All form fields, submission state, and error handling are managed in a single state object.
  1. Reducer Logic:
  • Actions (SET_FIELD, SUBMIT_START, etc.) describe what happens.

  • The reducer updates the state based on these actions.

  1. Form Submission:
  • On form submission, the state transitions smoothly through SUBMIT_START, SUBMIT_SUCCESS, or SUBMIT_ERROR.

Why Use This?

  • Scalability: Adding more fields or actions (like reset) is straightforward.

  • Readability: State transitions are centralized and predictable.

  • Performance: State updates are handled in bulk, reducing re-renders compared to multiple useState calls.

This skill is invaluable for managing complex state logic and making your React components more robust!

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

Top comments (0)

Image of AssemblyAI

Automatic Speech Recognition with AssemblyAI

Experience near-human accuracy, low-latency performance, and advanced Speech AI capabilities with AssemblyAI's Speech-to-Text API. Sign up today and get $50 in API credit. No credit card required.

Try the API

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay