Redux 状态管理:Store、Action 与 Reducer

FreeGuideOnline 最新 2026-06-15

什么是 Redux?

Redux 是一个用于 JavaScript 应用的可预测状态容器。它帮助你编写行为一致、可测试的应用,并且可以运行在不同环境(客户端、服务器、原生应用)中。核心思想是整个应用的状态被存储在一个单一的 Store 中,状态只能通过派发(dispatch)Action 来改变,而变化的逻辑由纯函数 Reducer 来定义。

相比组件间层层传递 props 或使用 Context,Redux 提供了一种集中式、可控的状态管理方式,特别适合中大型应用中的复杂状态逻辑。


Redux 核心三要素

Redux 的设计围绕以下三个不可分割的概念,理解它们就能掌握 Redux 的精髓。

Store —— 唯一的数据源

Store 是一个保存整个应用状态树的容器。在整个应用中只有一个 Store

  • 通过 createStore 方法创建(在 Redux Toolkit 中通常使用 configureStore)。
  • 提供 getState() 获取当前状态。
  • 提供 dispatch(action) 更新状态。
  • 允许通过 subscribe(listener) 注册监听器,状态变化时自动触发。
import { createStore } from 'redux';
import rootReducer from './reducers';

const store = createStore(rootReducer);

现代 Redux 推荐使用 @reduxjs/toolkit 中的 configureStore,它封装了更好的默认配置(如 Redux DevTools 和中间件)。

Action —— 描述“发生了什么”

Action 是一个普通的 JavaScript 对象,它是改变状态的唯一途径。Store 只能通过派发 Action 来触发状态更新。

Action 对象必须包含一个 type 字段,用于描述动作的类型(通常是字符串常量)。除此之外,可以携带任意数据作为 payload

// Action 示例
const addTodoAction = {
  type: 'todos/todoAdded',
  payload: '学习 Redux'
};

// 通常使用 Action Creator 函数来生成 Action
const addTodo = (text) => ({
  type: 'todos/todoAdded',
  payload: text
});

规则:永远不要直接修改状态,而是通过派发 Action 让 Reducer 返回新状态。这样可以保证数据流清晰可溯,方便调试和时间旅行。

Reducer —— 描述状态如何改变

Reducer 是一个纯函数,接收当前状态和 Action 作为参数,返回新的状态。它具体描述了 Action 如何将状态从旧值转变为新值。

(state, action) => newState

必须遵守的原则:

  • 不要直接修改传入的 state 参数(即不可变更新)。
  • 不能执行副作用(如 API 调用、路由跳转)。
  • 对于未知的 action type,必须返回原 state。
const initialState = { value: 0 };

function counterReducer(state = initialState, action) {
  switch (action.type) {
    case 'counter/incremented':
      return { ...state, value: state.value + 1 }; // 不可变更新
    case 'counter/decremented':
      return { ...state, value: state.value - 1 };
    default:
      return state;
  }
}

多个 Reducer 可以通过 combineReducers 组合起来,分别管理状态树的不同部分。


三者如何协作

Redux 的数据流是严格的单向流动

  1. Store 保存初始状态,并交给 dispatch 一个 Action。
  2. UI 中触发某个事件(如按钮点击),调用 store.dispatch(action)
  3. Store 将当前的 state 和收到的 action 传递给 Reducer
  4. Reducer 是一个纯函数,它计算并返回全新的 state,Store 会保存这个新状态。
  5. Store 通知所有订阅了它的 UI 组件,状态已更新,组件根据新数据重新渲染。

这个循环保证了状态的可预测性和可维护性,每一次状态变化都有迹可循。


使用 Redux Toolkit 简化代码

在现代 Redux 开发中,强烈推荐使用 Redux Toolkit (RTK)。它是官方推荐的工具集,解决了传统 Redux 上手难、样板代码多的问题。

创建 Slice(合并 Action 和 Reducer)

使用 createSlice 可以一次性定义状态、reducer 逻辑和相应的 action creator。

import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    incremented: (state) => {
      // Redux Toolkit 内部使用了 Immer,允许直接“修改”state
      state.value += 1;
    },
    decremented: (state) => {
      state.value -= 1;
    },
    incrementedByAmount: (state, action) => {
      state.value += action.payload;
    }
  }
});

export const { incremented, decremented, incrementedByAmount } = counterSlice.actions;
export default counterSlice.reducer;

配置 Store

import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';

const store = configureStore({
  reducer: {
    counter: counterReducer
  }
});

在 React 组件中使用

通过 react-redux 的 hooks 连接组件和 Store:

import { useSelector, useDispatch } from 'react-redux';
import { incremented, decremented } from './counterSlice';

function Counter() {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <button onClick={() => dispatch(decremented())}>-</button>
      <span>{count}</span>
      <button onClick={() => dispatch(incremented())}>+</button>
    </div>
  );
}

小结

  • Store:统一保管所有状态,通过 dispatch 触发变更。
  • Action:描述“要做什么”的对象,带有 type 和可选的 payload
  • Reducer:纯函数,定义状态如何响应 Action 并返回新状态。
  • Redux Toolkit:官方推荐工具,大幅简化 Redux 代码,使状态管理更直观高效。

掌握这三个核心概念,你就具备了使用 Redux 管理复杂应用状态的基础能力。下一步可以深入学习异步逻辑(如 createAsyncThunk)、实体适配器(createEntityAdapter)等高级特性。