You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
exportdefaultfunctionbindActionCreators(actionCreators,dispatch){if(typeofactionCreators==='function'){returnbindActionCreator(actionCreators,dispatch)}if(typeofactionCreators!=='object'||actionCreators===null){thrownewError(`bindActionCreators expected an object or a function, instead received ${actionCreators===null ? 'null' : typeofactionCreators}. `+`Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`)}constkeys=Object.keys(actionCreators)constboundActionCreators={}for(leti=0;i<keys.length;i++){constkey=keys[i]constactionCreator=actionCreators[key]if(typeofactionCreator==='function'){boundActionCreators[key]=bindActionCreator(actionCreator,dispatch)}}returnboundActionCreators}
exportdefaultfunctionapplyMiddleware(...middlewares){returncreateStore=>(...args)=>{conststore=createStore(...args)letdispatch=()=>{thrownewError(`Dispatching while constructing your middleware is not allowed. `+`Other middleware would not be applied to this dispatch.`)}constmiddlewareAPI={getState: store.getState,dispatch: (...args)=>dispatch(...args)}// 将整合出来的store和dispatch传递给中间件使用,并将中间件放在chain数组中constchain=middlewares.map(middleware=>middleware(middlewareAPI))dispatch=compose(...chain)(store.dispatch)// 再组合出新的 dispatchreturn{
...store,
dispatch
}}}
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
return enhancer(createStore)(reducer, preloadedState)
}
上一篇分析了createStore的源码,接下来分析剩下的文件。
combineReducers.js
combineReducers的作用在于将多个reducer转化为一个reducer,该函数接收reducer为参数,返回一个名为combination的函数。
首先一个for循环筛选出reducer中为functuon的key,并以key-value的方式存在finalReducers中,通过 const finalReducerKeys = Object.keys(finalReducers),
获取到reducer到key数组finalReducerKeys,在返回的函数中通过对finalReducerKeys循环逐一调用每一个reducer会生成一个新的值nextStateForKey,redux在这里直接直接比较新值
和之前的值,如果有变化则返回新值,没有则返回原来的值。
compose.js
参数为空或者只有一个时,直接返回该参数,当参数为多个时,则调用reducer,函数内部是一层一层函数的叠加,该函数参数在叠加的最内层调用.
bindActionCreators.js
bindActionCreators的作用就是将actionCreator和dispatch联结在一起。
该高阶函数是在文件内部使用,这个是为了减少重复代码,返回的函数中的参数传给的actionCreator函数执行,然后dispatch将其返回值作为参数再执行,其返回值作为该函数的返回值。
如果参数actionCreators为函数时,便直接执行bindActionCreator返回一个函数,如果参数为对象,通过循环其key值递归找到每一个对应的ActionCreator,
逐一执行bindActionCreator,最终返回一个对象。以下为具体用法:
applyMiddleware.js
applyMiddleware接收中间件为参数,并返回一个以createStore为参数的函数而这个函数返回store和dispatch;同时applyMiddleware又是createStore函数中的第三个参数,所以我们回到createStore的代码
当createStore中传了第三个参数的时候,会执行enhancer(createStore)(reducer, preloadedState),这是一个柯里化函数;我们可以设想中间件的使用方法:const store = createStore( reducer, applyMiddleware([...中间件]))。applyMiddleware([...中间件])的返回值是一个以createStore为参数的函数,这个函数会在createStore中执行,返回的函数也会继续执行,最后返回一个store。我们继续回到applyMiddleware中,在返回store之前,中间件做了什么处理呢?中间件将最重要的两个方法 getState/dispatch整合出来,并传递给中间件使用,中间件处理完之后,返回一个新的dispatch.
applyMiddleware把中间件放在一个chain数组中,并通过compose方法(我们上面已经介绍过了),让每个中间件按照顺序一次传入diapatch参数执行,再组合出新的 dispatch。由此可见,每个中间件的格式都应该是接收一个{ dispatch, getState },返回一个(dispatch) => { return function(action) { ... } }
The text was updated successfully, but these errors were encountered: