菜单

Actions 和 Reducers

相关源文件

Actions and reducers are the core building blocks of Redux state management. They work together to enable a predictable, unidirectional data flow in your application. This page explains what actions and reducers are, how they work together, and the rules and patterns for using them effectively.

For information about the Redux store itself, see Store API. For details about middleware and enhancers, see Middleware and Enhancers.

What are Actions?

Actions are plain JavaScript objects that represent "events" or "things that happened" in your application. They are the only way to send data from your application to your Redux store.

Actions must have a type property that identifies what kind of action it is. This is typically defined as a string constant. Actions may also contain additional data in a payload field or other custom fields.

Sources: docs/tutorials/fundamentals/part-1-overview.md189-197 docs/tutorials/fundamentals/part-3-state-actions-reducers.md193-211

操作类型

By convention, action types are strings that describe what happened. They're typically written in a format like "domain/eventName" where

  • The first part (domain) represents the feature or category
  • The second part (eventName) describes the specific action

It's recommended to use strings for action types because they're serializable, which helps for debugging and tools like Redux DevTools.

Sources: docs/faq/Actions.md26-34 docs/tutorials/fundamentals/part-3-state-actions-reducers.md214-232

Action Structure

The Redux action objects follow a flexible structure, but there are common patterns

  1. The type field is required and should be a string that describes what happened
  2. Optional payload field that contains any additional data
  3. Additional fields as needed for your application

The structure of the payload is up to you, though tools like Redux Toolkit and patterns like Flux Standard Action suggest using a single payload field for all action data.

Sources: docs/api/Store.md47-50 docs/tutorials/fundamentals/part-3-state-actions-reducers.md214-232

What are Action Creators?

Action creators are functions that create and return action objects. They encapsulate the process of creating an action, which makes your code more reusable and easier to test.

Action creators don't have to be complex - they can simply return an action object. The real benefit is that they centralize action creation logic, making it easier to update or modify actions later.

Sources: docs/tutorials/fundamentals/part-7-standard-patterns.md40-83 docs/api/bindActionCreators.md1-113

Redux Data Flow with Actions

The following diagram illustrates how actions flow through a Redux application

  1. A user interaction or other event happens in the UI
  2. Code dispatches an action to the Redux store
  3. The Redux store runs the reducer function with the current state and the action
  4. The reducer creates a new state based on the action type and payload
  5. The store updates its state and notifies all subscribers
  6. UI components connected to the store update with the new state

Sources: docs/tutorials/fundamentals/part-1-overview.md296-307 docs/tutorials/fundamentals/part-2-concepts-data-flow.md160-182

What are Reducers?

Reducers are pure functions that take the current state and an action as arguments, and return a new state. Reducers specify how the application's state changes in response to actions.

The basic signature of a reducer is

Reducers examine the action's type to determine how to update the state, and must return a new state object rather than mutating the existing state.

Sources: docs/tutorials/fundamentals/part-3-state-actions-reducers.md234-238 docs/tutorials/fundamentals/part-1-overview.md169-189

Reducer Rules

Reducers must follow these specific rules

  1. Calculate the new state based only on the state and action arguments

    • No API calls, no random values, no side effects
  2. Make immutable updates (no state mutations)

    • Create copies of objects and arrays before changing them
  3. Handle unknown actions

    • Return the existing state for any actions they don't recognize
  4. Initialize state

    • Provide an initial state value when undefined is passed as the state

These rules make Redux predictable and enable features like time-travel debugging.

Sources: docs/tutorials/fundamentals/part-3-state-actions-reducers.md323-353 docs/api/combineReducers.md74-85

Reducer Structure

A typical reducer is structured using a switch statement that handles different action types

While switch statements are most common, you can use any approach that properly handles different action types, including object lookups or more modern patterns available in Redux Toolkit.

Sources: docs/tutorials/fundamentals/part-3-state-actions-reducers.md287-319 docs/faq/Reducers.md15-28

Immutability in Reducers

Immutability is a core concept in Redux. Reducers must never mutate the state directly - they must make copies of any data they need to change.

Why Immutability Matters

  1. Predictability: Knowing exactly when and how state changes
  2. Performance: By comparing references, Redux can check if data has changed
  3. Debugging: Time-travel debugging relies on preserving previous states
  4. Correctness: React components only re-render when props change by reference

Sources: docs/tutorials/fundamentals/part-3-state-actions-reducers.md355-402 docs/faq/ReactRedux.md52-62

Immutable Update Patterns

Common techniques for making immutable updates

  1. Object spread operator for objects

  2. Array methods that return new arrays

  3. Immutable update libraries like Immer (built into Redux Toolkit)

Remember that immutable updates require copying at every level of nesting that needs to be updated.

Sources: docs/tutorials/fundamentals/part-3-state-actions-reducers.md394-402 docs/faq/ImmutableData.md

Combining Reducers

As applications grow, you'll want to split reducers into separate functions managing different parts of the state. Redux provides combineReducers to help with this.

How combineReducers Works

combineReducers takes an object where

  • The keys define the shape of the final state object
  • The values are reducer functions that manage those specific slices of state

This creates a structure where each reducer is responsible for its own slice of state, and the combined reducer creates a state object with the same shape as the reducer object.

Sources: docs/api/combineReducers.md12-53 docs/tutorials/fundamentals/part-3-state-actions-reducers.md438-449

Reducers 之间共享数据

虽然每个 reducer 都独立处理其状态片段,但所有 reducer 都会处理 action。这使得多个 reducer 可以响应同一个 action,从而在状态的不同部分实现协调更新。

如果一个 reducer 需要来自另一个状态片段的数据

  1. 考虑重构你的状态树
  2. 使用 thunks 或中间件通过 getState() 访问更多状态
  3. 创建自定义的根 reducer,超越 combineReducers

来源: docs/faq/Reducers.md21-30 docs/tutorials/fundamentals/part-3-state-actions-reducers.md488-505

Action 和 Reducer 协同工作

Action 和 reducer 之间的关系构成了 Redux 单向数据流的基础

  1. Actions 描述“发生了什么”,但不指定“状态如何改变”
  2. Reducers 决定“状态如何改变”以响应 actions
  3. 关注点的分离使系统可预测且易于维护

这种分离在 UI 事件、状态更改逻辑和渲染之间创建了清晰的边界。

来源: docs/tutorials/fundamentals/part-2-concepts-data-flow.md214-228 docs/faq/CodeStructure.md91-106

异步 Actions 和副作用

纯 reducer 不能包含副作用,如 API 调用或异步操作。对于这些操作,Redux 使用中间件(如 Redux Thunk)来启用异步 actions。

处理异步操作时

  1. 创建 actions 来跟踪请求状态(pending、fulfilled、rejected)
  2. 使用中间件在 reducers 之外管理异步逻辑
  3. 异步操作完成后,dispatch actions 来更新状态

我们将在 中间件和增强器 中更详细地介绍此主题。

来源: docs/tutorials/fundamentals/part-6-async-logic.md1-65 docs/faq/Actions.md17-22

最佳实践

以下是关于 Actions 和 Reducers 的一些推荐实践

Action 最佳实践

  1. 使用描述性的字符串 action types,格式为 domain/eventName
  2. 将尽可能多的信息放入 payload
  3. 使用 action creators 来封装 action 创建逻辑
  4. 将 actions 视为描述“发生了什么”的“事件”,而不是“setter”

Reducer 最佳实践

  1. 将 reducer 逻辑拆分成更小的函数来处理特定任务
  2. 将尽可能多的逻辑放入 reducers 中,而不是 action creators 中
  3. 始终使用不可变更新模式
  4. 用具体的业务逻辑谨慎处理每个 action
  5. 规范化复杂的嵌套数据结构

来源: docs/faq/CodeStructure.md91-106 docs/tutorials/fundamentals/part-7-standard-patterns.md40-83

使用 Redux Toolkit 简化

现代 Redux 开发通常使用 Redux Toolkit 来简化 actions 和 reducers

  1. createSlice 从单个配置生成 action creators 和 reducers
  2. Immer 集成允许编写“mutation”,这些 mutation 会变成不可变更新
  3. createAsyncThunk 简化了异步请求模式

通过 Redux Toolkit,手动创建 action types、action creators 和 switch 语句 reducers 被更简洁、更易于维护的模式所取代。

有关 Redux Toolkit 的更多信息,请参阅 使用 Redux Toolkit 进行现代 Redux 开发

来源: docs/tutorials/fundamentals/part-8-modern-redux.md194-264 docs/tutorials/fundamentals/part-8-modern-redux.md269-344

总结

  • Actions 是具有 type 字段的普通对象,用于描述“发生了什么”
  • Action creators 是创建并返回 action 对象的函数
  • Reducers 是纯函数,它们根据先前的状态和 action 计算新状态
  • Reducers 必须遵守规则,包括不可变更新和无副作用
  • combineReducers 有助于将 reducers 组织到状态树中
  • Redux 遵循单向数据流,其中 actions 通过 reducers 触发状态更新
  • 现代 Redux 使用 Redux Toolkit 来简化这些模式

理解 actions 和 reducers 是有效使用 Redux 的基础。这些概念构成了 Redux 可预测状态管理模式的核心。