Skip to main content

Redux Actions and Action Creators (Part 1) #107

?? Introduction

If reducers describe how state changes, actions describe what happened.

That distinction sounds simple, but it is one of the biggest reasons Redux scales well in production codebases. Instead of random mutations spread across components, Redux encourages an event-driven model: user and system events are represented as explicit action objects.

In practical React work, this makes behavior easier to inspect, easier to test, and easier to debug with tools like Redux DevTools.

This lesson focuses on action design. We will cover plain actions, action creators, naming patterns, payload structure, and how hooks-based React components dispatch these actions cleanly.


?? Prerequisites

Before continuing, review:

You should already understand reducers and immutable updates.


?? Article Outline: What You'll Master

By the end, you will:

  • Write clear, serializable Redux action objects.
  • Build action creators that reduce component noise.
  • Choose action type names that scale across features.
  • Dispatch actions from React components with useDispatch.

?? Section 1: What Is an Action?

An action is a plain JavaScript object with at least a type field.

{ type: 'cart/itemAdded', payload: { id: 'p7' } }

That type acts like a domain event name. It tells reducers what occurred. Optional fields like payload and meta carry relevant context.

Why plain objects?

  • They are serializable.
  • They are loggable.
  • They can be replayed in DevTools.
  • They are easy to test with simple equality checks.

Good Redux actions should represent events, not commands tied to implementation details.

Better:

{ type: 'checkout/submitted', payload: { orderId: 'o-991' } }

Worse:

{ type: 'setBooleanToTrue' }

The first tells a story. The second leaks low-level mechanics.


?? Section 2: Action Creators

Writing action objects inline is fine for tiny demos, but real apps quickly duplicate logic. Action creators keep that logic in one place.

// features/cart/cartActions.js
export const itemAdded = (id) => ({
type: 'cart/itemAdded',
payload: { id },
});

export const itemRemoved = (id) => ({
type: 'cart/itemRemoved',
payload: { id },
});

In a component:

import { useDispatch } from 'react-redux';
import { itemAdded } from './cartActions';

export function AddButton({ productId }) {
const dispatch = useDispatch();

return (
<button onClick={() => dispatch(itemAdded(productId))}>
Add to cart
</button>
);
}

Why this pattern helps:

  • Keeps action shape consistent.
  • Makes refactors safer (change once, use everywhere).
  • Simplifies testing because creators are pure functions.

?? Section 3: Naming Conventions That Scale

A useful convention is feature/eventName, for example:

  • auth/loginRequested
  • auth/loginSucceeded
  • auth/loginFailed
  • todos/todoAdded

Benefits:

  • Avoids type collisions across large apps.
  • Makes logs readable.
  • Improves reducer organization by feature.

Try to name actions after meaningful events in your product domain, not UI details. For example, profile/saved is often better than button/clicked.


?? Section 4: Testing Action Creators

Since action creators are pure, tests are straightforward:

import { itemAdded } from './cartActions';

test('itemAdded returns expected action', () => {
expect(itemAdded('p3')).toEqual({
type: 'cart/itemAdded',
payload: { id: 'p3' },
});
});

Simple tests like this catch accidental payload shape regressions early.


?? Section 5: Redux Toolkit Note

In modern code, createSlice can generate action creators for you. Even then, understanding plain action objects is essential because the architecture is unchanged.

Later in this chapter, especially in Why Redux Toolkit, you will see how toolkit reduces boilerplate while preserving Redux�s core flow.


?? Conclusion & Key Takeaways

Actions are the language of Redux state changes. They let your team describe application events in a consistent, inspectable format. Action creators keep that language organized and reusable across components.

Key takeaways:

  • Actions are plain objects with a type and optional payload.
  • Action creators reduce duplication and improve maintainability.
  • Event-oriented naming makes state transitions easier to reason about.
  • React components should dispatch meaningful events, not low-level mutations.

?? Next Steps

In Redux Actions and Action Creators (Part 2), we will build a richer end-to-end example and connect action flow to reducers and selectors.


glossary

  • Action: A plain object describing an event that happened.
  • Action Creator: A function that returns an action object.
  • Payload: Structured data carried by an action.
  • Type: String identifier used by reducers to branch logic.
  • Serializability: Ability to safely log/store/replay state and actions.

Further Reading