Redux Actions and Action Creators

Welcome to the tutorial on Redux Actions and Action Creators. If Redux is like a delivery system, then actions are the packages that contain the instructions for what should happen next. But instead of carrying physical goods, they carry instructions in the form of JavaScript objects!

Dispatching Actions and the Redux Loop

Actions are the only way to trigger changes to the Redux store. These actions are just plain JavaScript objects (POJOs) with a required type key and optional payload keys that contain new information.

You dispatch an action using store.dispatch(action). This is the spark that sets the Redux loop in motion. It's like pushing the first domino in a chain reaction.

Writing Action Creators

Imagine having to write the same action object repeatedly. That's repetitive! Instead, use a function to create these action objects dynamically. These functions are called action creators.

Folder Structure Example:

project_root/
├── src/
│   ├── actions/
│   │   └── fruitActions.js
│   └── store/
│       └── store.js
  

fruitActions.js:

// Action creator function
const addFruit = (fruit) => {
  return {
    type: 'ADD_FRUIT',
    fruit
  };
};

You can also simplify this using an implicit return:

const addFruit = (fruit) => ({
  type: 'ADD_FRUIT',
  fruit
});

Note: While shorter, implicit return functions make debugging harder since you can’t add console.log or debugger inside them.

Dispatching Actions with Action Creators

Once you have an action creator, you use it to create an action object, then dispatch it.

store.dispatch(addFruit('apple'));

This is equivalent to:

const appleAction = addFruit('apple');
store.dispatch(appleAction);

Using Constants for Action Types

Typing action type strings manually invites errors. One typo and things break silently! Instead, define action types as constants:

const ADD_FRUIT = 'ADD_FRUIT';

const addFruit = (fruit) => {
  return {
    type: ADD_FRUIT,
    fruit
  };
};

This ensures consistency and reduces bugs. If you mistype ADD_FRUIT, you'll get an error, helping catch issues early.

Ducks Naming Convention

You might see action types written like this:

const ADD_FRUIT = 'groceryApp/fruit/ADD_FRUIT';

This is called the Ducks convention. It’s like adding a return address on your packages, so you know exactly where they came from. It helps with organization in larger apps.

Important: Actions Trigger, Reducers Update

Analogy: Actions are like orders in a restaurant, and reducers are the chefs. Orders don’t cook food; chefs do. Similarly, actions don’t update the state; reducers do based on the action’s type.

When an action is dispatched, the reducer checks the type and decides how to update the state accordingly.

Follow-Along Exercise

Let’s practice:

  1. Create a file called fruitActions.js in your src/actions folder.
  2. Define an action type constant ADD_FRUIT.
  3. Create an action creator addFruit that takes a fruit name and returns an action object.
  4. In your store.js, dispatch the action using store.dispatch(addFruit('banana')).

Real-World Example

In a to-do list app, you might have actions like ADD_TODO, REMOVE_TODO, and TOGGLE_TODO. Each would have an action creator function, making your app easier to scale and maintain.

Why Use Action Creators and Constants?

Further Exploration

Summary

Actions are the lifeblood of Redux state changes. You learned how to:

Actions are triggers, not doers. Reducers do the heavy lifting. Keep this in mind as you build more complex Redux applications.

Resources

Check out the official Redux documentation for more details: Redux Documentation