上一章Redux教程请查看:redux reducer
Redux本身是同步的,那么像网络请求这样的异步操作是如何与Redux一起工作的呢?在这里,中庸之道就派上用场了。如前所述,reduce是编写所有执行逻辑的地方,reduce与执行它的人无关,与它花费了多少时间无关,也与在调度操作之前和之后记录应用程序的状态无关。
在这种情况下,Redux中间件功能提供了一个媒介,可以在它们到达reducer之前与分派的动作进行交互。可以通过编写高阶函数(返回另一个函数的函数)来创建定制的中间件函数,这些函数封装了一些逻辑。可以将多个中间件组合在一起以添加新功能,而且每个中间件都不需要知道之前和之后发生了什么,你可以想象中间件介于调度的动作和reducer之间。
通常情况下,中间件用于处理应用程序中的异步操作。Redux提供了一个名为applyMiddleware的API,它允许我们使用定制中间件以及Redux中间件,比如Redux -thunk和Redux –promise,它将中间件应用于存储,使用applyMiddleware API的语法是——
applyMiddleware(...middleware)
这可以应用到下面的存储中:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';
const store = createStore(rootReducer, applyMiddleware(thunk));
中间件允许你编写一个返回函数而不是动作对象的动作调度程序。下面是同样的例子:
function getUser() {
return function() {
return axios.get('/get_user_details');
};
}
条件分派可以在中间件中编写,每个中间件接收store的分派,以便它们可以分派新的操作,而getState函数作为参数,以便它们可以访问当前状态并返回一个函数,内部函数的任何返回值都可以作为分派函数本身的值使用。
下面是中间件的语法:
({ getState, dispatch }) => next => action
getState函数用于根据当前状态决定是获取新数据还是返回缓存结果。
让我们来看一个定制中间件日志记录器功能的示例,它只记录操作和新状态。
import { createStore, applyMiddleware } from 'redux'
import userLogin from './reducers'
function logger({ getState }) {
return next => action => {
console.log(‘action’, action);
const returnVal = next(action);
console.log('当发送动作时state', getState());
return returnVal;
}
}
现在,通过编写以下代码将日志记录器中间件应用于存储:
const store = createStore(userLogin , initialState=[ ] , applyMiddleware(logger));
使用下面的代码来分派一个动作来检查分派的动作和新的状态:
store.dispatch({
type: 'ITEMS_REQUEST',
isLoading: true
})
下面给出了另一个中间件示例,你可以在其中处理何时显示或隐藏加载程序。这个中间件在你请求任何资源时显示加载程序,并在完成资源请求时隐藏它。
import isPromise from 'is-promise';
function loaderHandler({ dispatch }) {
return next => action => {
if (isPromise(action)) {
dispatch({ type: 'SHOW_LOADER' });
action
.then(() => dispatch({ type: 'HIDE_LOADER' }))
.catch(() => dispatch({ type: 'HIDE_LOADER' }));
}
return next(action);
};
}
const store = createStore(
userLogin , initialState = [ ] ,
applyMiddleware(loaderHandler)
);