一、Redux中间件的使用
import reducer from './reducer';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk'
const initState = {
todoList:[
{id:'1',text:'游泳',complete:false},
{id:'2',text:'冥想',complete:false},
{id:'3',text:'工作',complete:false},
{id:'4',text:'午休',complete:false},
{id:'5',text:'追番',complete:false},
]
}
const middlewraes = applyMiddleware(thunk);
const store = createStore(reducer,initState,middlewraes);
// asyncAdd现在可以处理异步请求了
const mapDispatchToProps = (dispatch) => {
return {
asyncAdd:(id)=>{
dispatch(()=>{
getItem(id).then(res=>{
dispatch(res)
})
});
}
}
};
<Button onClick={() => props.asyncAdd(id)}>增加</Button>
二. 实现思路
const store = {
dispatch: function (action) {
console.log(action);
}
};
const logger1 = store => next => action => {
console.log('日志中间件1', action);
return next(action);
};
const logger2 = store => next => action => {
console.log('日志中间件2', action);
return next(action);
}
function applyMiddleware(middlewares) {
middlewares.forEach(middleware => {
store.dispatch = middleware(store)(store.dispatch);
});
}
// redux-thunk
const thunk = store => next => action => {
if (typeof action === "function") {
return action(store);
} else {
return next(action)
}
};
applyMiddleware([logger1, logger2, thunk].reverse());
store.dispatch(() => {
console.log('dispatch的是一个函数');
});
store.dispatch({ type: 'DELETE', id: 1 });
- 这里applyMiddleware的作用是时dispatch可以接收一个函数,并使用函数柯理化编排middleware。
- redux-thunk的逻辑也很简单,判断如果action是个函数就执行这个action,否则继续执行编排后的柯理化函数。
- 注意函数执行的顺序,[thunk,logger2,logger1 ]的执行顺序是logger1、logger2、thunk。thunk必须放到最后执行,否则会提前执行action,漏掉其它中间件的执行。
三、实现自己的redux中间件
知道了redux中间件原理后,现在来手动实现一个中间件
// 实现一个中间件拦截action并修改其中的text属性
const customMiddleware = store => next => action => {
const { dispatch, getState } = store;
return next({ ...action, text: '拦截修改后的文字' })
}
// 应用
const middlewraes = applyMiddleware(thunk, customMiddleware);
这里要注意redux-thunk必须放到最后执行
四、使用reducer实现中间件
function logNum(num){
console.log(num);
return num;
};
const add2 = next => num=>{
console.log('add2');
return next(num+2);
};
const mult5 = next => num =>{
console.log('mult5');
return next(num*5)
};
function compose(middlewares,fn){
return middlewares.reduce((preFn,nextFn)=> nextFn(preFn),fn)
};
const foo = compose([add2,mult5], logNum)(10);
console.log(foo); //52
传送门: 函数柯理化的链式调用