跳到主要内容

核心

核心包括 Store(储存)Action(动作)Reducer(规约器)、和 Middleware(中间件)

  • Store:状态的唯一容器,提供状态管理和基础能力
  • Action:描述状态变更的原因,是驱动流程的起点
  • Reducer:纯函数,根据 Action 计算新状态,保证可预测性
  • Middleware:扩展 Redux 功能,处理副作用和复杂逻辑

一、Store(存储):状态的唯一容器

Store 是 Redux 应用的状态管理中心,全局唯一,符合储存应用的完整状态树(State Tree)。

1. 核心功能

  • 状态储存:保存应用的当前状态(state),状态是只读的,只能通过 dispatch(action) 触发更新
  • 派发动作:提供 dispatch(action) 方法,用于触发状态更新的入口
  • 状态订阅:提供 subscribe(listener) 方法,允许组件或其他模块订阅状态变化(监听回调会在更新后被调用)
  • 获取状态:提供 getState() 方法,用于获取当前状态树的快照
  • 动态替换:提供 replaceReducer(nextReducer) 动态替换 Reducer 用于代码分割

2. 创建方式

Redux 原生通过 createStore(reducer, [preloadedState], [enhancer]) 创建 Store,但是现代实践中更推荐使用 Redux ToolkitconfigureStore() ,它集中了常用优化(如中间件、不可变更新工具):

import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './reducers';

const store = configureStore({
reducer: rootReducer, // 合并后的根 Reducer
preloadedState: {}, // 初始状态(可选)
});

3. 关键特性

  • 单一数据源:整个应用的状态储存在唯一的 Store 中,便于调试和状态追踪
  • 状态只读:必须通过 dispatch(action) 触发 Reducer 更新状态,避免直接修改

二、 Action (动作):描述状态变化的意图

Action 是一个 普通 JavaScript 对象,用于描述“发生了什么”,是驱动状态变化的起点。它的核心是传递状态变声的意图。

1. 基本结构

Action 必须是一个 type 属性(标识动作类型),其他属性可选(通常携带数据,成为 payload):

//  基础 Action
{ type : 'ADD_TODO' , payload: '学习 Redux'}

// 更简洁的写法(约定 payload 为数据字段)
{type: 'ADD_TODO', text: '学习 Redux'} // 非强制,但推荐统一规范

2. 类型(Type)

  • 字符串常量:通常定义为常量(如 export const ADD_TODO = "ADD_TODO"),避免拼写错误
  • 命名空间:推荐用模块前缀避免冲突(如 todos/ADD_TODO

3. 扩展 Action (需 Middleware 支持)

同步 Action 直接描述状态变更,而异步操作(如 API 请求)需要 Middleware (如 redux-thunk)支持。此时 Action Creator 可以返回函数而非对像:

// 异步 Action Creator (依赖 redux-thunk)
const fetchUser = userId => async dispatch => {
dispatch({ type: 'USER_FETCH_START' }); // 开始加载
try {
const response = await api.getUser(userId);
dispatch({ type: 'USER_FETCH_SUCCESS', payload: response.data }); // 成功
} catch (error) {
dispatch({ type: 'USER_FETCH_FAILURE', payload: error.message }); // 失败
}
};

4. Redux 创建 Action

Redux 提供了实用程序函数来帮助 action :

  • createAction(type, payloadCreator):创建 Action 创建函数
  • createAsyncThunk(type, payloadCreator):创建异步 Action 创建函数
  • createSlice(options):创建 Reducer 和 Action 创建函数的集合
// 使用 createAction
const increment = creteAction('INCREMENT');

// 使用 createAsyncThunk
const fetchUserData = createAsyncThunk('FETCH_USER_DATA', async userId => {
const response = await fetch('/user/'.concat(userId));

return response.json();
});

// 在组件使用

import { useDispatch } from 'react-redux';

const Counter = () => {
const dispatch = useDispatch();

const handleIncrement = () => {
dispatch(increment());
};

return <button onClick={handleIncrement}>+</button>;
};

三、 Reducer (规约器):状态更新的纯函数

Reducer 是一个纯函数,负责根据 Action 类型和当前状态,计算并返回新的状态。其命名源于函数式编程中的“规约”(Reducer)操作。

1. 函数签名

(previousState, action) => newState;
  • 输入:当前状态(previousState) 和触发更新 Action 对象
  • 输出:新的状态对象(必须返回新对象,而非修改原状态)

2. 核心规则

  • 纯函数:相同的输入必须得到相同的输出,禁止副作用(如 API 调用、修改外部变量)
  • 不可变更新:必须返回新的状态对象(如 [...state, newItem]),而非直接修改原状态(state.push(newItem)
  • 处理未知 Action:为匹配到 Action 类型时,返回原状态(保持状态不变)

3. 示例

// todos Reducer
const initialState = [];

function todosReducer(state = initialState, action) {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{ id: Date.now(), text: action.text, completed: false },
];
case 'TOGGLE_TODO':
return state.map(todo =>
todo.id === action.id ? { ...todo, completed: !todo.completed } : todo,
);
default:
return state; // 未匹配的 Action 返回原状态
}
}

4. 组合 Reducer

复杂应用的状态树通常拆分为多个子状态,通过 combineReducers() 合并为根 Reducer:

// Redux Toolkit 主动处理,原生 Redux 需要手动组合
import { combineReducers } from 'redux';

const rootReducer = combineReducers({
todos: todosReducers,
user: userReducer,
// ... 其他子 Reducer
});

四、 Middleware(中间件):扩展 Redux 能力

Middleware 是 Redux 的“插件系统”,用于处理 副作用(如异步操作、日志记录、奔溃日志)或扩展 Redux 流程。它位于 dispatch(action) 和 Reducer 之间,允许拦截、修改或观察 Action。

1. 核心作用

2. 工作原理

Middleware 通过函数组合实现链式调用,每个 Middleware 接收 store 作为参数,并返回一个增强 dispatch 的函数。

const middleware = store => next => action => {
// 前置逻辑(如日志记录)
console.log('Dispatching: ', action);
// 调用下一个 Middleware 或 Reducer
const result = next(action);
// 后置逻辑(如打印更新后的状态)
console.log('New state: ', store.getState());
return result;
};

3. 常用 Middleware 示例

  • redux-thunk:允许 Action Creator 返回函数(而非对象),函数接收 dispatchgetState 作为参数,用于处理异步逻辑(最常用)
  • redux-saga:基于 Generator 函数的中间件,适合管理复杂异步流程(如竞态条件、取消请求)
  • redux-logger:自动打印 Action、旧状态和新状态,用于调试

4. 配置方式

通过 applyMiddleware() 将 Middleware 应用到 Store。

// 原生 Redux 配置
import { creteStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const store = createStore(
rootReducer,
applyMiddleware(thunk, logger), // 多个 Middleware 按顺序执行
);

// Redux Toolkit 自动集成(默认包含 thunk)
import { configureStore } from '@reduxjs/toolkit';

const store = configureStore({
reducer: rootReducer,
middleware: getDefaultMiddleware => getDefaultMiddleware().concat(logger),
});

五、 协同工作流程

Redux 的核心流程可总结为 “触发 Action ➞ Middleware 处理 ➞ Reducer 计算新状态 ➞ Store 更新 ➞ 订阅者响应“

  • 用户交互:组件(如 React 组件)触发事件(如按钮点击)
  • 派发 Action:调用 store.dispatch(action),传递 Action 对象(可能异步可能同步)
  • Middleware 拦截:Middleware 链依次处理 Action (如异步请求完成后生成新的 Action )
  • Reducer 更新状态:最终 Action 到达 Reducer,根据 action.type 计算新状态
  • 状态变更通知:Store 更新后,调用所有 subscribe 注册的监听器(如组件重新渲染)