redux给我们介绍redux,暴露了这些方法{createStore,combineReducers,bindActionCreators,applyMiddleware,compose}下面依次介绍createStore创建store的方式:letstore=createStore(reducer,preloadedState,enhancer);createStore中的三个参数reducer,preloadedState,enhancer,后两个是可选参数,当我们只传两个参数时,第二个参数是一个函数,例如:letstore=createStore(reducer,enhancer);通过阅读源码if(typeofpreloadedState==='function'&&typeofenhancer==='undefined'){enhancer=preloadedStatepreloadedState=undefined}我们知道上面的createStore会改写如下:createStore(educer,undefined,enhancer)然后阅读源代码:if(typeofenhancer!=='undefined'){if(typeofenhancer!=='function'){thrownewError('Expectedtheenhancertobeafunction.')}returnenhancer(createStore)(reducer,preloadedState)}你会发现原来的调用方式又变了,变成了下面的方式enhancer(createStore)(reducer,undefined)于是实例化一个createStore方法,下面两个是等价的:第一个conststore=createStore(reducers,applyMiddleware(routeMiddleware,sagaMiddlew是,postRedirectMiddleware,pageSizeMiddleware));第二个conststore=applyMiddleware(routeMiddleware,sagaMiddleware,postRedirectMiddleware,pageSizeMiddleware)(createStore)(reducers);最后,返回的store对象提供了以下方法供我们使用dispatch、subscribe、getState、replaceReducer、getState用于获取currentState,即状态总值。订阅注册多个监控功能。这些函数会在开发者调用dispatch的时候依次执行。dispatch的入参是一个对象action,会直接执行reducer(action)方法,并执行批量订阅监控内容。dispatch执行后,会返回一个actionreplaceReducer来替换当前的reducer。此方法可用于异步单个应用程序。比如我们不想一次性把所有reducer都交给createStore来初始化。而是在异步抓取一个页面时,将这个页面的reducer添加到旧的reducer中,通过replaceReducer方法替换为最新的reducer。这样做的好处是devtools中的redux工具不会显示那么多信息。只会显示访问页面的信息,更有利于我们的开发。当然,由于reducer的减少,store的体积也会变小,页面执行速度也会变快。combineReducers源代码导出默认函数combineReducers(reducers){constreducerKeys=Object.keys(reducers)constfinalReducers={}for(leti=0;iarg}if(funcs.length===1){returnfuncs[0]}returnfuncs.reduce((a,b)=>(...args)=>a(b(...args)))}个人认为compose(a,b,c)(d)之后的代码是a(b(c(d))),和compose之后返回的仍然是一个可以接受参数的函数。后面介绍的代码中涉及到Compose。applyMiddleware源代码exportdefaultfunctionapplyMiddleware(...middlewares){returncreateStore=>(...args)=>{conststore=createStore(...args)letdispatch=()=>{thrownewError(`Dispatching同时构建你的中间件是不允许的。`+`其他中间件不会应用于此分派。`)}letchain=[]constmiddlewareAPI={getState:store.getState,dispatch:(...args)=>dispatch(...args)}chain=middlewares.map(middleware=>middleware(middlewareAPI))dispatch=compose(...chain)(store.dispatch)return{...store,dispatch}}}创建一个store的方法:letstore=applyMiddleware(middleware1,middleware2,middleware3)(createStore)(reducers)中间件middleware1的代码functionmiddleware1({getState}){return(next)=>(action)=>{console.log('willdispatch',action)letreturnValue=next(action)console.log('dispat后的状态ch',getState())returnreturnValue}}applyMiddleware传入的参数是多个中间件。中间件的作用是在执行reducer中的switch之前,先执行源代码中参数对应的中间件中的代码,实例参数middleware1和middleware2相当于源码入参...middlewares,实例参数createStore对应源码入参createStore,实例参数reducers对应源码入参...args。源码中的conststore=createStore(...args)获取store对象,以备后用。middlewareAPI中的getState对应store对象中的getState。getState()方法可以获得currentState,即redux对象树的总数据。chain=middlewares.map(middleware=>middleware(middlewareAPI))middlewareAPI为中间件提供getState方法获取currentState。这时候chain得到的数组就是一个函数,其返回值是一个函数。下面这行代码更精彩。dispatch=compose(...chain)(store.dispatch)首先使用最原始的store.dispatch方法作为入参,dispatch(action)相当于compose(...chain)(store.dispatch)(action),也等同于middleware1(middleware2(middleware3((store.dispatch))))(action),当然这里的middleware1在闭包中只有两层函数,并不是原来的三层函数体。首先执行的是middleware1,返回next(action),相当于middleware2(middleware3((store.dispatch)))(action),执行完返回next(action)相当于middleware3((store.dispatch)))(action),执行后返回next(action)相当于store.dispatch(action)的整个过程我们已经搞清楚了,applyMiddleware中间件的执行过程是连续的next(action),而且只有最后一个next是执行调度。previousnext只表示传递其他中间件,dispatch方法只在最后一个中间件执行一次。个人觉得这个地方结合compose后更精彩,设计的很巧妙。