Setcina(目前还在更新以及完善中...)

03-使用redux的中间件

2019-02-11

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
    6
    let 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
8
import { 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
    12
    const 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。

Tags: Redux

扫描二维码,分享此文章