🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
REFERENCEreact

react Documentation

LOADING ENGINE...

Actions

AI & DATA SCIENCE // actions

An action is a plain JavaScript object describing something that happened, with a required type field and typically a payload carrying any additional data, and is the only way to trigger a state change in Redux.

Syntax

{ type: 'ADD_TODO', payload: { text: 'Buy milk' } }

Deep Dive Course

Actions are the sole mechanism for communicating an intent to change state in Redux — a component dispatches an action object, and the store passes it, along with the current state, to the reducer, which decides how, if at all, the state should change in response. By convention, an action's type field is a string, often written in SCREAMING_SNAKE_CASE or namespaced like 'todos/add', describing what happened in past tense or as an event name, and any additional data the reducer needs is typically bundled under a payload field, an established convention rather than a strict requirement enforced by Redux itself.

1Understanding Actions

Actions are the sole mechanism for communicating an intent to change state in Redux — a component dispatches an action object, and the store passes it, along with the current state, to the reducer, which decides how, if at all, the state should change in response. By convention, an action's type field is a string, often written in SCREAMING_SNAKE_CASE or namespaced like 'todos/add', describing what happened in past tense or as an event name, and any additional data the reducer needs is typically bundled under a payload field, an established convention rather than a strict requirement enforced by Redux itself.

💡

An action object should describe what happened, not how the state should change — the reducer, not the action, is responsible for deciding exactly how a given action actually transforms the state, keeping that decision logic centralized in one place rather than scattered across wherever actions happen to be dispatched.

editor.html
const addTodoAction = {
  type: 'todos/add',
  payload: { text: 'Buy milk', done: false }
};

console.log(addTodoAction.type, addTodoAction.payload.text);
localhost:3000

2Practical Example

Here is a real-world application of Actions showing how it is used in production React code.

editor.html
function addTodo(text) {
  return {
    type: 'todos/add',
    payload: { text, done: false }
  };
}

console.log(addTodo('Walk the dog'));
localhost:3000

3Best Practices

Follow these guidelines when working with Actions:

1. Give every action a clear, descriptive type field, conventionally namespaced like 'todos/add', describing what happened rather than how state should change

2. Bundle any additional data an action carries under a payload field, following Redux's common, though not strictly enforced, action-object convention

3. Keep actions themselves as plain, simple data, no functions or class instances, so they remain fully serializable, which is exactly what enables tools like Redux DevTools to record and replay them

⚠️

Tip: An action object should describe what happened, not how the state should change — the reducer, not the action, is responsible for deciding exactly how a given action actually transforms the state, keeping that decision logic centralized in one place rather than scattered across wherever actions happen to be dispatched.

editor.html
const addTodoAction = {
  type: 'todos/add',
  payload: { text: 'Buy milk', done: false }
};

console.log(addTodoAction.type, addTodoAction.payload.text);
localhost:3000

Examples

Example 01Basic Usage
const addTodoAction = {
  type: 'todos/add',
  payload: { text: 'Buy milk', done: false }
};

console.log(addTodoAction.type, addTodoAction.payload.text);
Example 02Advanced Example
function addTodo(text) {
  return {
    type: 'todos/add',
    payload: { text, done: false }
  };
}

console.log(addTodo('Walk the dog'));

Best Practices

  • Give every action a clear, descriptive type field, conventionally namespaced like 'todos/add', describing what happened rather than how state should change
  • Bundle any additional data an action carries under a payload field, following Redux's common, though not strictly enforced, action-object convention
  • Keep actions themselves as plain, simple data, no functions or class instances, so they remain fully serializable, which is exactly what enables tools like Redux DevTools to record and replay them

Interview Question

Why does Redux require dispatched actions to be plain, serializable data objects, rather than allowing something like a function or a class instance describing the change?

Hint: Think about what capabilities, like recording, replaying, or persisting a sequence of actions, depend on each individual action being genuinely plain, inspectable data.

Keeping actions as plain, serializable objects, essentially just data that could be converted to and from JSON without losing any information, is exactly what makes it possible for tools like Redux DevTools to record a complete, ordered history of every action dispatched throughout a session, display each one in a readable, inspectable form, and even replay that exact sequence later to reconstruct any past application state, called time-travel debugging. If an action could be an arbitrary function or a class instance, it might capture, or close over, values from the specific moment it was created, become impossible to meaningfully serialize to JSON for logging, persistence, or replay, and behave inconsistently depending on when it's actually invoked rather than remaining a fixed, faithful record of exactly what happened. Restricting actions to plain data objects guarantees every action can always be reliably logged, saved, transmitted, and replayed identically, which is foundational to much of Redux's tooling and predictability.

Exercises

MediumPractice using Actions in a real scenario.
View Solution
const addTodoAction = {
  type: 'todos/add',
  payload: { text: 'Buy milk', done: false }
};

console.log(addTodoAction.type, addTodoAction.payload.text);

Frequently Asked Questions

Why does Redux require dispatched actions to be plain, serializable data objects, rather than allowing something like a function or a class instance describing the change?

Keeping actions as plain, serializable objects, essentially just data that could be converted to and from JSON without losing any information, is exactly what makes it possible for tools like Redux DevTools to record a complete, ordered history of every action dispatched throughout a session, display each one in a readable, inspectable form, and even replay that exact sequence later to reconstruct any past application state, called time-travel debugging. If an action could be an arbitrary function or a class instance, it might capture, or close over, values from the specific moment it was created, become impossible to meaningfully serialize to JSON for logging, persistence, or replay, and behave inconsistently depending on when it's actually invoked rather than remaining a fixed, faithful record of exactly what happened. Restricting actions to plain data objects guarantees every action can always be reliably logged, saved, transmitted, and replayed identically, which is foundational to much of Redux's tooling and predictability.

Related Functions

reducersusedispatchstore