← 返回目录

第 10 卷

第 10 / 28 卷日期:

• 示例(登录异步请求):

• 核心原理:通过“生成器函数(generator)”编写异步逻辑,将异步流程与组件解耦,支持更复

杂的异步场景(如取消请求、请求竞态处理、定时任务)。

• 核心思路:监听特定的 action,当 action 被 dispatch 时,执行对应的生成器函数处理异步逻辑,

异步完成后 dispatch 同步 action。

方式 3:使用 redux-observable(基于 RxJS,响应式编程):

• 核心原理:基于 RxJS 库,将 action 视为“数据流”,通过响应式操作符(如 switchMap、

catchError)处理异步逻辑,适合需要复杂数据流控制的场景(如实时数据推送)。

2. Redux 中间件的定义与作用

Redux 中间件是 Redux 生态中“扩展 dispatch 功能”的核心机制,本质是一个“函数”,位于“组件 dispatch action”和“reducer 处理 action”之间,对 action 进行拦截、处理或转换,实现额外

的功能。

(1)核心作用

  • 处理异步逻辑:如网络请求、定时器等(这是最常用的作用);
  • 日志打印:记录每一次 action 的触发、状态的变化,便于调试(如 redux-logger);
  • 状态校验:拦截 action,校验状态更新是否符合规范,避免非法状态修改;
  • action 转换:将收到的 action 转换为其他 action,再传递给 reducer。

(2)工作位置

Redux 原始流程:组件 → dispatch(action) → reducer → store 更新 → 组件渲染;

加入中间件后流程:组件 → dispatch(action) → 中间件(拦截、处理 action) → reducer → store 更新 → 组件渲染。

3. 编写 Redux 中间件的步骤(自定义中间件)

Redux 中间件遵循“柯里化函数”的规范,结构为“三层函数嵌套”:

Code block

1// 中间件核心结构(三层函数)

2const customMiddleware = store => next => action => {
3//中间件逻辑
4//执行完成后,调用next(action)将action传递给下一个中间件或reducer
5next(action);

• 第一层函数(store):接收 Redux 的 store 对象,可通过 store.getState() 获取当前状

态, store.dispatch() 触发新的 action;

• 第二层函数(next):接收“下一个中间件的 dispatch 方法”(若没有下一个中间件,则是原始

的 reducer 处理函数),调用 next(action) 可将 action 传递下去;

• 第三层函数(action):接收组件 dispatch 的 action,在此层编写核心处理逻辑(如异步、日

志、校验等)。

(1)自定义中间件示例 1:日志中间件(记录 action 和状态变化)

Code block

1const loggerMiddleware = store => next => action => {
2// 1.记录触发的action
3console.log('触发action:', action);
4// 2.记录当前状态(action处理前)
5console.log('处理前状态:', store.getState());
6// 3.将action传递给下一个中间件或reducer
7const result = next(action);
8// 4.记录处理后的状态
9console.log('处理后状态:', store.getState());
10// 5.返回结果(可选,便于后续中间件使用)
11return result;
12};

(2)自定义中间件示例 2:异步中间件(简化版 redux-thunk)

Code block

1const asyncMiddleware = store => next => action => { 2// 核心逻辑:如果 action 是函数,则执行函数(传入 dispatch 和 getState);否则传递给

下一个中间件 3if (typeof action === 'function') {

4return action(store.dispatch, store.getState());
5}
6//非函数action,正常传递
7return next(action);
8 };

(3)应用自定义中间件

4import asyncMiddleware from './middleware/asyncMiddleware';

5 6// 创建 store 时应用中间件

7const store = createStore( 8rootReducer,

9applyMiddleware(asyncMiddleware, loggerMiddleware) // 中间件执行顺序:从左到右 10);

11 12export default store;

二十、Redux 状态管理器与全局对象来保存数据有什么不同?

Redux 状态管理器和“全局对象保存数据”(如 window.globalState = { ... })都能实现“数据全局共享”,但两者在“状态管理规范性、可维护性、调试能力、生态支持”等方面差异巨

大,Redux 本质是“规范化的全局状态管理方案”,而全局对象是“简单的全局数据存储”,具体差异如下:

对比维度Redux 状态管理器全局对象(如 window.globalState)

状态修改规范有严格的修改规范:必须通无任何规范:可在任意位置直
过“dispatch(action) →接修改(如
reducer → 新状态”的流程修window.globalState.use
改,不允许直接修改状态(状r = 'admin'),状态修改
态不可变),确保状态变化可逻辑分散,容易出现“不知道
预测。哪里修改了状态”的问题,维

护成本高。

状态变化追踪支持状态变化追踪:配合无状态追踪能力:修改状态后
Redux DevTools 可查看每一无法追溯修改来源、修改时
次状态变化的历史(包括触发间,调试时需要手动打印日
的 action、旧状态、新状志,排查问题困难。

态),支持“时间旅行”(回退到任意历史状态),调试效

率极高。

组件联动更新自动联动更新:组件通过无自动联动更新:修改全局对
subscribe 或象后,依赖该数据的组件不会
useSelector 订阅状态变自动重新渲染,需要手动调用
全站分卷索引 · 28 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷
  20. 20第 20 卷
  21. 21第 21 卷
  22. 22第 22 卷
  23. 23第 23 卷
  24. 24第 24 卷
  25. 25第 25 卷
  26. 26第 26 卷
  27. 27第 27 卷
  28. 28第 28 卷