redux中间件
在上面的redux学习中我们可以发现我们的代码执行都是同步的,那么如果我们需要操作异步的程序,比如在发送ajax请求那么我们应该如何操作呢?
对于node的中间件,大家应该不会陌生。react的中间件概念和node差不多。都是为了拓展功能。
上面的代码都是同步进行的,如果我们请求了后台数据,那么使用同步方法是不可行的。我们在reducer中进行异步操作也是不可以的,因为reducer是一个纯函数。我们在action的时候操作呢?也是不可以的,action只能是一个对象,不支持函数。那么我们应该怎么操作异步数据呢?在store.dispatch(action)
这里可以吗?在不使用中间件的情况下是不可以的,因为store.dispatch(action)
的action参数只能是一个对象,并不支持函数。那么我们需要拓展store.dispatch(action)
的功能,让他可以传入函数。我们会使用到中间件,来扩展他。
为了理解中间件,让我们站在框架作者的角度思考问题:如果要添加功能,你会在哪个环节添加?
(1)Reducer:纯函数,只承担计算 State 的功能,不合适承担其他功能,也承担不了,因为理论上,纯函数不能进行读写操作。
(2)View:与 State 一一对应,可以看作 State 的视觉层,也不合适承担其他功能。
(3)Action:存放数据的对象,即消息的载体,只能被别人操作,自己不能进行任何操作。
中间件的使用
import {
applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
const store = createStore(
reducer,
applyMiddleware(thunk)
);
上面代码中,redux-logger
提供一个生成器createLogger
,可以生成日志中间件logger
。然后,将它放在applyMiddleware
方法之中,传入createStore
方法,就完成了store.dispatch()
的功能增强。
这里有两点需要注意:
(1)createStore
方法可以接受整个应用的初始状态作为参数,那样的话,applyMiddleware
就是第三个参数了。
const store = createStore( reducer, initial_state, applyMiddleware(logger) );
(2)中间件的次序有讲究。
const store = createStore( reducer, applyMiddleware(thunk, promise, logger) );
上面代码中,applyMiddleware
方法的三个参数,就是三个中间件。有的中间件有次序要求,使用前要查一下文档。比如,logger
就一定要放在最后,否则输出结果会不正确。
redux-thunk
redux-thunk就是redux的一个中间件,用于处理异步操作。
Action 是由store.dispatch
方法发送的。而store.dispatch
方法正常情况下,参数只能是对象,不能是函数。
这时,就要使用中间件redux-thunk
。
import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import reducer from './reducers'; // Note: this API requires redux@>=3.1.0 const store = createStore( reducer, applyMiddleware(thunk) );
上面代码使用redux-thunk
中间件,改造store.dispatch
,使得后者可以接受函数作为参数。
因此,异步操作的第一种解决方案就是,写出一个返回函数的 Action Creator,然后使用redux-thunk
中间件改造store.dispatch
。
redux-saga
redux-saga
也用于解决异步问题。更偏向于模块化。
使用过Umi的同志们肯定对这个saga会比较熟悉。他和redux-thunk的功能差不多,使用起来会比redux-thunk复杂一些。
cnpm install redux-sage --save
import reactSageMiddleware from 'redux-sage'
import reactSageMiddleware from "redux-saga";
const sageMiddlware = reactSageMiddleware();
const store = createStore(reducer,sageMiddlware)
sageMiddlware.run(mySages)
完成上述操作一个react-saga就已经可以使用了。如果需要使用那么推荐大家前往官网学习。