Reducer Functions, Actions, and Dispatch0%

Reducer Functions, Actions, and Dispatch

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

Reducer Functions, Actions, and Dispatch

1. The Anatomy of Reducer Architecture

The reducer pattern rests on three interconnected pillars:

  1. 1
    The State: The current data snapshot of your component or feature.
  2. 2
    The Action: A plain JavaScript object describing an event that occurred.
  3. 3
    The Dispatch Function: The communication channel used to send actions to the reducer.
  4. 4
    The Reducer: The pure decision-maker function that calculates the next state.
Output
[User clicks "Enroll"]
│
▼
dispatch({ type: 'ENROLL_STUDENT', payload: { id: 42, name: 'Ananya' } })
│
▼
[Pure Reducer Function: (state, action) => newState]
│
▼
[React updates state and triggers re-render]

2. Anatomy of an Action Object

By convention across the JavaScript and React ecosystem (Flux Standard Action pattern), an action object contains:

  • type (Required): A descriptive string in UPPER_SNAKE_CASE or domain/event format stating what happened.
  • payload (Optional): Any data required to execute the transition (e.g. an ID, an input string, an object).
JavaScript
// Examples of descriptive, semantic actions:
{ type: 'TODO_ADDED', payload: 'Master React Reducers' }
{ type: 'FILTER_CHANGED', payload: 'completed' }
{ type: 'ITEM_DELETED', payload: 104 }
{ type: 'FORM_RESET' }

3. Writing Pure Reducer Functions

A reducer must adhere strictly to the rules of pure functions:

  • Zero Side Effects: Never initiate API calls, start timers, modify localStorage, or trigger random numbers inside a reducer.
  • Strict Immutability: Never mutate state in place. Always use object spread (...state) and non-mutating array methods (map, filter).
  • Deterministic: Given the same state and action, it must always return the exact same output.
JSX
export const initialCartState = {
items: [],
discountCode: null,
totalPrice: 0
};
 
export function cartReducer(state, action) {
switch (action.type) {
case 'ADD_ITEM': {
const existingIndex = state.items.findIndex(i => i.id === action.payload.id);
let updatedItems;
 
if (existingIndex > -1) {
// Increment quantity immutably
updatedItems = state.items.map((item, idx) =>
idx === existingIndex ? { ...item, quantity: item.quantity + 1 } : item
);
} else {
// Add new item immutably
updatedItems = [...state.items, { ...action.payload, quantity: 1 }];
}
 
return {
...state,
items: updatedItems,
totalPrice: updatedItems.reduce((acc, i) => acc + i.price * i.quantity, 0)
};
}
 
case 'REMOVE_ITEM': {
const filtered = state.items.filter(i => i.id !== action.payload);
return {
...state,
items: filtered,
totalPrice: filtered.reduce((acc, i) => acc + i.price * i.quantity, 0)
};
}
 
case 'APPLY_DISCOUNT': {
return {
...state,
discountCode: action.payload,
totalPrice: state.totalPrice * 0.9 // 10% off
};
}
 
case 'CLEAR_CART':
return initialCartState;
 
default:
// Return unchanged state or throw error for unrecognized actions
return state;
}
}

4. The Stability of dispatch

In React, the dispatch function returned by useReducer is guaranteed to have a stable identity across all renders.

React guarantees that dispatch will never change its reference between re-renders. This means:

  • You do not need to include dispatch in useEffect or useCallback dependency arrays.
  • Passing dispatch down through props or Context will never trigger unnecessary child re-renders!

Interactive Quiz

Practice Quiz

Question 1
What two properties are standard on a Flux Standard Action object?
Question 2
What should happen if a reducer receives an unknown action type that it does not handle?
Question 3
Why is performing an asynchronous fetch() inside a reducer function strictly forbidden?
Question 4
Does the dispatch function returned by useReducer change reference between component re-renders?
Question 5
What makes reducers exceptionally easy to unit test compared to components?
Next Lesson

Managing Complex State Transitions with useReducer

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext