1.Redux 的基本做法:用户发出 Action,Reducer 函数算出新的 State,View 重新渲染。
2.但是,一个关键问题没有解决:异步操作怎么办?Action 发出以后,Reducer 立即算出 State,这叫做同步;Action 发出以后,过一段时间再执行 Reducer,这就是异步。
怎么才能 Reducer 在异步操作结束后自动执行呢?这就要用到新的工具:中间件(middleware)。
为了理解中间件,让我们站在框架作者的角度思考问题:如果要添加功能,你会在哪个环节添加?
(1)Reducer:纯函数,只承担计算 State 的功能,不合适承担其他功能,也承担不了,因为理论上,纯函数不能进行读写操作。
(2)View:与 State 一一对应,可以看作 State 的视觉层,也不合适承担其他功能。
(3)Action:存放数据的对象,即消息的载体,只能被别人操作,自己不能进行任何操作。
想来想去,只有发送 Action 的这个步骤,即store.dispatch()方法,可以添加功能。举例来说,要添加日志功能,把 Action 和 State 打印出来,可以对store.dispatch进行如下改造。1
2
3
4
5
6let next = store.dispatch;
store.dispatch = function dispatchAndLog(action) {
console.log('dispatching', action);
next(action);
console.log('next state', store.getState());
}
上面代码中,对store.dispatch进行了重定义,在发送 Action 前后添加了打印功能。这就是中间件的雏形。
中间件就是一个函数,对store.dispatch方法进行了改造,在发出 Action 和执行 Reducer 这两步之间,添加了其他功能。
3.中间件的用法1
2
3
4
5
6
7
8import { applyMiddleware, createStore } from 'redux';
import createLogger from 'redux-logger';
const logger = createLogger();
const store = createStore(
reducer,
applyMiddleware(logger)
);
上面代码中,redux-logger提供一个生成器createLogger,可以生成日志中间件logger。然后,将它放在applyMiddleware方法之中,传入createStore方法,就完成了store.dispatch()的功能增强。
这里有两点需要注意:
(1)createStore方法可以接受整个应用的初始状态作为参数,那样的话,applyMiddleware就是第三个参数了。
1
2
3
4
5
6
7
8
9
10
11
12const store = createStore(
reducer,
initial_state,
applyMiddleware(logger)
);
```
* >(2)中间件的次序有讲究。
``` js
const store = createStore(
reducer,
applyMiddleware(thunk, promise, logger)
);
上面代码中,applyMiddleware方法的三个参数,就是三个中间件。有的中间件有次序要求,使用前要查一下文档。比如,logger就一定要放在最后,否则输出结果会不正确。
4.看到这里,你可能会问,applyMiddlewares这个方法到底是干什么的?
它是 Redux 的原生方法,作用是将所有中间件组成一个数组,依次执行。
5.使用redux-thunk中间件,改造store.dispatch,使得后者可以接受函数作为参数。
因此,异步操作的第一种解决方案就是,写出一个返回函数的 Action Creator,然后使用redux-thunk中间件改造store.dispatch。
扫描二维码,分享此文章