//源码使用方法
import {createStore, applyMiddleWare} from 'redux';
//createStore.js的源码
export default function createStore(reducer, preloadState, enhancer) {
//...
if(typeof enhancer !== 'undefined'){
if(typeof enhancer !== 'function'){
throw new Error('...')
}
}
//enhancer是一个增加强器,是可选参数。是applyMiddelWare的返回值即一个函数
return enhancer(createStore)(reducer, preloadState); }
//顾名思义, applyMiddleWare就是对各个需要应用的中间件进行糅合,并作为createStore的
//第二个或者第三个参数传入,用于增强store。源码如下:
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
}
}
}
//分析:
export default function applyMiddleware(...middlewares);
//这里使用了扩展运算符,使得applyMiddleware可以接收任意个数的中间件。接下来,
//applyMiddleware会返回一个函数,这个函数接收了一个next参数:
return (next) => (reducer, initialState) => {
//...
}
//对应于createStore.js代码,applyMiddelware作为一个三级柯里化的函数,它的执行相当于:
applyMiddleware(...middlewares)(store)(reducer, initialState);
//这样做的目的是借用原始的createStore方法,创建一个增强版store,具体看其内容实现:
var store = createStore(reducer, initialState);
var dispatch = store.dispatch;
var chain = []
//这里记录了原始的store和store.dispatch方法,并准备了一个chain数组
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
var chain = middlewares.map(middleware => middleware(middlewareAPI));
//middlewareAPI是第三方中间件需要使用的参数,即原始的store.getState 和dispatch方法,
//这些参数在中间件中是否会全部应用到,自然要看每个中间件的应用场景和需求。
//可以想象chain数组中每一项都是对原始dispatch的增强,并进行控制权转移。所以就有了 dispatch = compose(...chain, store.dispatch)
//这里的dispatch函数就是增强后的dispatch。因此,compose 方法接收了chain数组和原始的store.dispatch方法。
export default function compose (...funcs) {
if(funcs.length === 0){
return arg => arg;
}
if(funcs.length === 1){
return funcs[0];
}
return funcs.reduce((a, b) => (...args) => a(b(...args)));
}
//实际上,compose方法就像是把多个中间件串联起来,就像
// middlewareA( middlewareB( middlewareC(store.dispatch) ) )