在 Redux 中,中间件是对 dispatch
函数进行扩展的一种方式,用来处理 action
和 store
之间的通信和交互。中间件的作用可以分为两类:一类是应用领域逻辑相关的中间件,一类是通用的、与应用领域逻辑无关的中间件。
Redux 需要中间件的原因是:通过中间件可以实现 action 和 store 之间的断点,方便地对 action 进行拦截和处理,在 action 到达 reducer 之前,执行某些额外操作(如日志记录、异步请求、错误处理等),或是对 action 进行修改。同时,由于 Redux 的单向数据流特性,中间件可以很好地控制整个应用程序中的数据流,使代码具有更加可读性和可维护性。
上一篇分享介绍了Redux的工作流程,其中修改store中数据是通过store.disptch方法传递action信号来达到目的,这是同步修改state的方式。可是真正项目中经常会通过Ajax请求到数据再修改store。
javascriptexport const doSomeing = (text) => { return (dispatch) => { dispatch({ type: 'LOAD_MORE_WORK', msg: 'pending', }); fetch('<http://levenx.com>').then(resp => { // console.log('[resp]', resp.status); if (resp.status === 200) return resp.json(); throw new Error('not 200 this time'); // 美滴很 }).then(json => { /* 2. 异步结束了,发结果action */ dispatch({ type: 'LOAD_MORE_WORK', msg: json.name, }); }).catch(error => { /* 3. 倒霉催的,发报错action */ dispatch( { type: 'do', payload: text } ); }); } }
我们希望action可以处理异步动作,如果不借助中间件来处理的话,会报错。
store
接受action传递到信号是一个对象,即
action
方法返回的是object,但是处理异步操作时,我们使用如上代码,
action
传递给
store
的是一个function,如果没有中间件帮忙处理一下,
store
是不接受的。
react-thunk就是来解决异步问题的。
basnpm install react-thunk
javascriptimport { createStore, applyMiddleware,compose} from 'redux'; import thunk from 'redux-thunk'; import reducer from './reducer' const initState = { money: 0 }; //redux devtools 和 其他中间件 一起使用时,需要做如下判断 const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose; const enhancer = composeEnhancers( applyMiddleware(thunk) ); //创建store工厂 const store = createStore( reducer, initState, enhancer ); export default store;
初始化store时,注入react-thunk,action便可以返回function,react-thunk通过异步请求的不同状态disptch给 store对应的object对象作为信号。
使用效果如下图,每次action修改state时,都会在控制台打印出关键信息,便于开发者追溯状态。
配置:
javascriptimport { createStore, applyMiddleware, compose } from 'redux'; import thunk from 'redux-thunk'; import logger from 'redux-logger' import reducer from './reducer' const initState = { money: 0 ,levenx:''}; const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose; const enhancer = composeEnhancers( applyMiddleware(thunk, logger) ); //创建store工厂 const store = createStore( reducer, initState, enhancer ); export default store;
后续再补一些其他的中间件的使用。中间件都是方便我们日常开发的,好用的中间件还是很有必要了解一下。