- 对 redux 而言,同步指的是当视图发出 action 以后,reducer 立即算出 state(原始的redux工作流程),而异步指的是在 action 发出以后,过一段时间再执行 reducer。
- 同步通常发生在原生 redux 的工作流程中,而在大多数实际场景中,更多的是需要异步操作:action 发出以后,在进入 reducer 之前需要先完成一个异步任务,比如发送 ajax 请求后拿到数据后,再进入 reducer 执行计算并对 state 进行更新。
- 显然原生的 redux 是不支持异步操作的,这就要用到新的工具——中间件(middleware)来处理这种业务场景。从本质上来讲中间件是对 store.dispatch 方法进行了拓展。
- 中间件提供位于 action 发起之后,到达 reducer 之前的扩展点:即通过 store.dispatch 方法发出的 action 会依次经过各个中间件,最终到达 reducer。
- 我们可以利用中间件来进行日志记录(redux-logger)、创建崩溃报告(自己写crashReporter)、调用异步接口(redux-saga)或者路由(connected-react-router)等操作。
- redux 提供了一个原生的 applyMiddleware 方法,它的作用是将所有中间件组成一个数组,依次执行。假如要使用 redux-logger 来实现日志记录功能,用法如下:
import { applyMiddleware, createStore } from 'redux';
import createLogger from 'redux-logger';
const logger = createLogger();
const store = createStore(
reducer,
applyMiddleware(logger)
);
- 如果有多个中间件,则将中间件依次作为参数传入 applyMiddleware 方法中:
import { applyMiddleware, createStore } from 'redux';
import createLogger from 'redux-logger';
import createSagaMiddleware from 'redux-saga';
const logger = createLogger(); // 日志记录
const sagaMiddleware = createSagaMiddleware(); // 调用异步接口
let middleware = [sagaMiddleware];
middleware.push(logger);
const store = createStore(
reducer,
// 可传initial_state
applyMiddleware(...middleware)
);
需要注意⚠的是:
- createStore 方法可以接受整个应用的初始状态作为参数(可选),若传入初始状态,applyMiddleware 则需要作为第三个参数。
- 有的中间件有次序要求,使用前要查一下文档(如 redux-logger一定要放在最后,否则输出结果会不正确)。