React useReducer for Complex State — Forms, State Machines, and Redux Patterns
Master useReducer for complex state management in React. Covers form state, state machines, combining with useContext for global state, and when to choose useReducer over useState.
State Hooks
Detailed Explanation
Complex State with useReducer
useReducer is an alternative to useState that excels at managing complex, interdependent state transitions.
When to Choose useReducer
- State has multiple sub-values that update together
- Next state depends on previous state
- You want to centralize and test state logic
- You need to pass dispatch (stable reference) to deep children
Form State Example
interface FormState {
name: string;
email: string;
errors: Record<string, string>;
submitting: boolean;
}
type FormAction =
| { type: "SET_FIELD"; field: string; value: string }
| { type: "SET_ERRORS"; errors: Record<string, string> }
| { type: "SUBMIT_START" }
| { type: "SUBMIT_SUCCESS" }
| { type: "RESET" };
function formReducer(state: FormState, action: FormAction): FormState {
switch (action.type) {
case "SET_FIELD":
return { ...state, [action.field]: action.value, errors: {} };
case "SET_ERRORS":
return { ...state, errors: action.errors, submitting: false };
case "SUBMIT_START":
return { ...state, submitting: true, errors: {} };
case "SUBMIT_SUCCESS":
return { name: "", email: "", errors: {}, submitting: false };
case "RESET":
return { name: "", email: "", errors: {}, submitting: false };
}
}
State Machine Pattern
useReducer naturally maps to state machines, making impossible states impossible:
type State =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: User[] }
| { status: "error"; error: string };
Mini Redux with useReducer + useContext
Combine useReducer with useContext to create a global state container without external libraries. Pass the dispatch function through context -- it has a stable identity and does not cause unnecessary re-renders.
Use Case
Use useReducer for multi-step forms, shopping carts, data fetching state machines, and any scenario where you want centralized, testable state transitions.