廢話不多說奸汇,直接上干貨:
首先說下middleware怎么用
store = createStore(reducer, applyMiddleware(middleware, middleware2));
下面先來看createStore里面干了什么拴驮,直接上源碼(去除了里面的方法)
export default function createStore(reducer, preloadedState, enhancer) {
if (
(typeof preloadedState === 'function' && typeof enhancer === 'function') ||
(typeof enhancer === 'function' && typeof arguments[3] === 'function')
) {
throw new Error(
'It looks like you are passing several store enhancers to ' +
'createStore(). This is not supported. Instead, compose them ' +
'together to a single function.'
)
}
//這里主要做了一下參數(shù)處理送巡,讓enhancer正確指向applyMiddleware返回的函數(shù)
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
enhancer = preloadedState
preloadedState = undefined
}
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
//這里直接調(diào)用了applyMiddleware返回方法
return enhancer(createStore)(reducer, preloadedState)
}
if (typeof reducer !== 'function') {
throw new Error('Expected the reducer to be a function.')
}
let currentReducer = reducer
let currentState = preloadedState
let currentListeners = []
let nextListeners = currentListeners
let isDispatching = false
//沒有使用中間件的話直接返回store
return {
dispatch,
subscribe,
getState,
replaceReducer,
[$$observable]: observable
}
}
看了上面createStore的源碼捧颅,我們有兩個(gè)結(jié)論:
1.在沒有使用中間件的時(shí)候,我們的createStore直接返回了一個(gè)store對象
2.在使用了中間件的時(shí)候我們的createStore直接調(diào)用了applyMiddleware返回的方法
問題:
在使用中間件的時(shí)候store在哪創(chuàng)建的黄锤?
別著急搪缨,下面我們來看applyMiddleware里面做了什么
export default function applyMiddleware(...middlewares) {
return createStore => (...args) => {
const store = createStore(...args)
let dispatch = () => {
throw new Error(
'Dispatching while constructing your middleware is not allowed. ' +
'Other middleware would not be applied to this dispatch.'
)
}
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
const chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
果然applyMiddleware返回一個(gè)方法(這里是一個(gè)柯里化的寫法)
在上面我們說過在使用中間件的時(shí)候createStore執(zhí)行的是一個(gè)applyMiddleware返回的方法,
并傳入了兩個(gè)參數(shù)
return enhancer(createStore)(reducer, preloadedState)
return createStore => (...args) => {}
再結(jié)合源碼鸵熟,都對上了此時(shí)createStore對應(yīng)的是上面?zhèn)鬟M(jìn)來的createStore副编,...args對應(yīng)的是上面?zhèn)魅氲?br>
(reducer, preloadedState)
接著看這里
//這個(gè)時(shí)候再調(diào)用createStore由于第二個(gè)參數(shù)不是一個(gè)方法,而且也不存在第三個(gè)參數(shù)流强,所以直接返回了store
const store = createStore(...args)
原來store是在這個(gè)地方創(chuàng)建的痹届,這里存在一個(gè)很隱蔽的遞歸調(diào)用呻待,終于知道了(松了一口氣)