在没有引入中间件时,社会治理子系统在开发时,所有的action都是同步的,一个同步的action对象是一个包含type字段的简单对象,但是我们需要实现一个异步action对象,是一个函数,在action触发之后,在reducer接收到执行命令之前可以进行一个异步操作。
我们引入redux-thunk来实现异步访问服务器方法,一个访问服务器的action,至少要涉及三个action类型:
表示异步操作已经开始的action类型;
表示异步操作成功的action类型;
表示异步操作失败的action类型;
Redux-thunk源代码解析
Redux-thunk中间件是Redux中异步操作的解决方法之一,在action对象被reducer函数处理之前,是插入异步功能的时机,代码非常简单:
function create ThunkMiddleware(extraArgument){ return ({dispatch, getState}) => next => action => { if(typeof action === ‘function'){ return action(dispatch, getState, extraArgument); } return next(action) } } const thunk = createThunkMiddleware(); export default thunk;
createThunkMiddleware函数返回了一个函数,是实际处理每个action对象的函数,首先检查参数action的类型,如果是函数类型的话,就执行这个action函数,把dispatch和getState
作为参数传递出去,否则就调用next让下一个中间件继续处理action。
Redux-thunk的使用:
首先,安装redux-thunk,在已经安装了node.js的命令窗口中运行 “npm install redux-thunk --save-dev”,在store.js中引入redux-thunk,并且确保redux的applyMiddleware函数也引入。具体实现代码如下。
import {createStore, combineReducers, applyMiddleware} from ‘redux'; import {otherState, dataState} from ‘reducers'; import thunkMiddleware from ‘redux-thunk'; var reducers = combineReducers({ otherState, dataState }); var store = createStore(reducers, applyMiddleware(thunkMiddleware)); export default store;
在成功引入了redux-thunk后,我们也要设计异步操作的action对象,例如,在设备管理模块中,成功保存设备信息后要重新获取设备信息,代码如下:
function saveInfo(params){ let url = “/api/device”; return function(dispatch, getState){ dispatch(saveInfoRequest()); return Http.get(url, { params: params }).then(res=>{ if(res && res.type === 0){ dispatch(saveInfoSuccess ()); let dataState = getState().dataState; let newParams = { start: dataState.start, limit: dataState.limit, searchName: dataState.searchName }; dispatch(getInfo(newParams)) } }).catch(error=>{ dispatch(saveInfoFailure (error)); }); } }
从这个saveDeviceInfo返回的函数中,不仅可以dispatch一个同步的action对象,还可派发另一个异步action对象,来满足一些有着先后关系的业务逻辑,代码可读性要比用Promise实现起来代码更加清晰。
Redux-logger使用
在开发阶段,我们需要对redux数据流中每个流程进行监控,需要log输出,redux-logger是官方推荐的一款日志中间件,使用起来非常方便。当然,要使redux-logger生效,需要保证在系统中使用redux进行状态管理,否则没有任何日志输出。
Redux-logger的使用方法可以分为两种,基本使用方法如下:
import { applyMiddleware, createStore} from ‘redux'; import logger from ‘reudx-logger' const store = createStore( Reducer, applyMiddleware(logger) )
也可以自己写一个日志输出中间件,代码如下:
var logger = store => next => action => { console.log('[action]', action) console.log(`[action] type:${action.type} payload:${JSON.stringify(action.payload)}`) next(action) console.log('[store]', store.getState()) console.log(`[store] ${JSON.stringify(store.getState())}`) }
总结
Redux中间件可以增强Store.dispatch方法,多个中间件可以组成“管道”,按照顺序去处理action对象,在依次处理过后,才会有机会被reducer处理。中间件的应用场景很多,除了可以支持异步访问服务器,还有许多很好的中间件插件,例如react-addons-perf进行调试,和redux-logger来记录状态,也可以根据业务需求来自己编写中间件,应用非常灵活,在其他react项目中可以多加实践。