Defining Actions and Reducers for WordPress Data Stores
Master the WordPress Data layer by implementing formal Actions and Reducers. Learn to manage state mutation predictably in your React-based admin dashboard.
Previously in this course, we explored registering a custom data store and writing selectors for data access. Now that you have a store registered and a way to read data, it’s time to define how that data changes.
In the WordPress data architecture, you don't mutate state directly. Instead, you dispatch Actions—plain JavaScript objects describing what happened—which are then processed by Reducers—pure functions that determine how the state should update. This separation is the key to predictable state mutation.
The Anatomy of Actions and Reducers
Think of an action as an event notification. It contains a type (a string describing the action) and an optional payload (the data needed to perform the update).
A reducer is a function that takes the current state and an action, and returns the new state. Because reducers must be pure, they cannot modify the original state object; they must always return a new, updated version. If you've ever wrestled with React state management: Reducers vs. State Machines, you know that this functional approach is the best way to avoid side-effect bugs.
Creating Action Creators
While you could dispatch raw objects, we use Action Creators—functions that return these objects—to ensure consistency and simplify the dispatching process.
JAVASCRIPT// store/actions.js export function setKnowledgeBaseItems(items) { return { type: CE9178">'SET_ITEMS', items, }; } export function updateItemStatus(id, status) { return { type: CE9178">'UPDATE_ITEM_STATUS', id, status, }; }
Defining Reducer Logic
Your reducer is the brain of your data store. It listens for the actions you just defined and updates the state accordingly. You should use a switch statement to handle different action types.
JAVASCRIPT// store/reducer.js const DEFAULT_STATE = { items: [], }; export function reducer(state = DEFAULT_STATE, action) { switch (action.type) { case CE9178">'SET_ITEMS': return { ...state, items: action.items, }; case CE9178">'UPDATE_ITEM_STATUS': return { ...state, items: state.items.map((item) => item.id === action.id ? { ...item, status: action.status } : item ), }; default: return state; } }
Notice how we use the spread operator (...state) to ensure we aren't mutating the existing state object. This follows the principles of TypeScript Immutability: Stopping Mutation Bugs in State Management by ensuring every state transition results in a new object reference.
Dispatching Actions to the Store
To trigger these updates from your React components, you use the dispatch function provided by the @wordpress/data registry.
JAVASCRIPTimport { useDispatch } from CE9178">'@wordpress/data'; import { STORE_NAME } from CE9178">'./constants'; const MyComponent = () => { const { setKnowledgeBaseItems } = useDispatch(STORE_NAME); const handleRefresh = async () => { const items = await fetchItems(); // Your service layer setKnowledgeBaseItems(items); }; return <button onClick={handleRefresh}>Refresh Items</button>; };
Hands-on Exercise
- Open your
store/reducer.jsfile. - Add a new action type
REMOVE_ITEMto your reducer that filters theitemsarray based on a providedid. - Create a corresponding action creator in
store/actions.jscalledremoveItem(id). - Dispatch this action from a "Delete" button in your Knowledge Base admin list component and verify that the UI updates instantly.
Common Pitfalls
- Mutating State Directly: Never use
state.items.push()orstate.items[0] = value. Always return a new array or object. If you mutate, the WordPress data store won't trigger re-renders because it won't detect a change in reference. - Non-Serializable Payloads: Keep your action payloads simple. Avoid passing class instances or DOM nodes. Stick to plain JSON-serializable data (strings, numbers, arrays, objects).
- Over-complicating Reducers: If your reducer logic is becoming massive, split it into smaller sub-reducers. A reducer should handle one slice of the state tree.
Recap
We've established that actions describe what happened, and reducers define how the state changes in response. By dispatching actions through the store, we ensure that our Knowledge Base plugin remains maintainable and that UI updates are strictly tied to state transitions.
Up next: Implementing Resolvers for Data Fetching.
Work with me

Custom WordPress Plugin Development
Custom WordPress & WooCommerce plugins built to standard — by the developer behind a plugin with 5,000+ active installs and a SaaS with 10,000+ users.

WooCommerce Store Setup & Customization
A WooCommerce store that's set up right, customized to your brand, and ready to sell — by a developer who builds WooCommerce products, not just stores.