redux深入进阶
闲话不多说,上代码。 如何加载中间件import { createStore,applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import rootReducer from './reducers/index'; // create a store that has redux-thunk middleware enabled const createStoreWithMiddleware = applyMiddleware( thunk )(createStore); const store = createStoreWithMiddleware(rootReducer); 这里需要用到 这显然是一个装饰器模式,通过不同的中间件对 瞬间觉得别人都是码神,而我就是码农有木有/(ㄒoㄒ)/~~ 中间件加载机制的实现先来看 import compose from './compose'; /** * Creates a store enhancer that applies middleware to the dispatch method * of the Redux store. This is handy for a variety of tasks,such as expressing * asynchronous actions in a concise manner,or logging every action payload. * * See `redux-thunk` package as an example of the Redux middleware. * * Because middleware is potentially asynchronous,this should be the first * store enhancer in the composition chain. * * Note that each middleware will be given the `dispatch` and `getState` functions * as named arguments. * * @param {...Function} middlewares The middleware chain to be applied. * @returns {Function} A store enhancer applying the middleware. */ export default function applyMiddleware(...middlewares) { return (next) => (reducer,initialState) => { var store = next(reducer,initialState); var dispatch = store.dispatch; var chain = []; var middlewareAPI = { getState: store.getState,dispatch: (action) => dispatch(action) }; chain = middlewares.map(middleware => middleware(middlewareAPI)); dispatch = compose(...chain)(store.dispatch); return { ...store,dispatch }; }; } 这就是redux里面这个方法的源码,其中还一半是注释有木有。。。本来以为肯定有百来行代码的 从这里开始代码就有点绕了,我们逐行分析 return (next) => (reducer,initialState) => {...} 整个 function (reducer,initialState) { var store = next(reducer,initialState); // next即为最初的createStore方法 // ...以下省略 } var store = next(reducer,initialState); var dispatch = store.dispatch; var chain = []; 这里没什么好讲的,首先创建了一个store,这个store就是最原始的通过 var middlewareAPI = { getState: store.getState,dispatch: (action) => dispatch(action) }; chain = middlewares.map(middleware => middleware(middlewareAPI)); dispatch = compose(...chain)(store.dispatch); 这里是关键,必须详细进行讲解。 首先,这边声明了一个
然后 chain = middlewares.map(middleware => middleware(middlewareAPI)); 我们来仔细看看这行代码,首先我们对所有的中间件进行一个map,map结果就是调用中间件方法,将 export default function thunkMiddleware({ dispatch,getState }) { return next => action => typeof action === 'function' ? action(dispatch,getState) : next(action); }
我们回顾之前的代码,在map所有中间件的时候我们调用了 function (next) { return function (action) { typeof action === 'function' ? action(dispatch,getState) : next(action) } } 于是我们接下去分析 chain = middlewares.map(middleware => middleware(middlewareAPI)); 现在我们知道chain是一个数组,每一项是调用每个中间件之后的返回函数 dispatch = compose(...chain)(store.dispatch); compose是redux里面的一个帮助函数,代码如下: export default function compose(...funcs) { return arg => funcs.reduceRight((composed,f) => f(composed),arg); }
我们看到这边先调用了 function (arg) { return funcs.reduceRight((composed,arg); // funcs就是中间件数组 } 然后我们把 // 假设中间件数组是[A,B,C] // 那么结果就是A(B(C(store.dispatch))) 再次结合 function (action) { typeof action === 'function' ? action(dispatch,getState) : next(action) } // 这里的next方法,就是真正的store.dispatch方法 // 这里的dispatch是(action) => store.dispatch(action) 我们再结合 function incrementAsync() { return dispatch => { setTimeout(() => { // Yay! Can invoke sync or async actions with `dispatch` dispatch(increment()); },1000); }; } 这是使用 dispatch(incrementAsync())
function (dispatch) { setTimeout(() => { // Yay! Can invoke sync or async actions with `dispatch` dispatch(increment()); },1000); } 这个时候我们回想经过中间件加工的 function (action) { typeof action === 'function' ? action(dispatch,getState) : next(action) } // 这里的next方法,就是真正的store.dispatch方法 // 这里的dispatch是(action) => store.dispatch(action) action是一个函数,所以 我们再接着想,如果我们有许多个中间件,那么没一个中间件的 以上的代码非常绕,建议去专研一下源码。这么精简的代码包含了非常多的函数式编程的思想,也用到了装饰器模式的原理,不得不说:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |