createStore在redux類庫(kù)中是篇幅最長(zhǎng)的一個(gè)函數(shù)。它主要的作用是構(gòu)建redux的store。
當(dāng)createStore函數(shù)遇到enhance參數(shù)
function createStore(reducer, preloadedState, enhancer)
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
return enhancer(createStore)(reducer, preloadedState)
}
在createStore函數(shù)中,只要enhancer存在,創(chuàng)建store的過(guò)程將會(huì)在enhancer函數(shù)中完成。這保證了可以在enhancer函數(shù)中裝飾和包裝dispatch核心方法。有興趣可看:applyMiddleware源碼分析
dispatch函數(shù):
function dispatch(action) {
if (!isPlainObject(action)) {
throw new Error(
'Actions must be plain objects. ' +
'Use custom middleware for async actions.'
)
}
if (typeof action.type === 'undefined') {
throw new Error(
'Actions may not have an undefined "type" property. ' +
'Have you misspelled a constant?'
)
}
if (isDispatching) {
throw new Error('Reducers may not dispatch actions.')
}
//這就是為什么reducer函數(shù)處理返回?cái)?shù)據(jù)出現(xiàn)錯(cuò)誤也不報(bào)錯(cuò)的原因。
//直接在dispatch函數(shù)內(nèi)進(jìn)行錯(cuò)誤處理,reducer處理action的錯(cuò)誤并不會(huì)報(bào)給開(kāi)發(fā)者。
//(真坑爹,這導(dǎo)致開(kāi)發(fā)者很難進(jìn)行錯(cuò)誤追蹤。)
try {
isDispatching = true
currentState = currentReducer(currentState, action)
} finally {
isDispatching = false
}
const listeners = currentListeners = nextListeners
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
listener()
}
return action
}
初始化store的state
// When a store is created, an "INIT" action is dispatched so that every
// reducer returns their initial state. This effectively populates
// the initial state tree.
dispatch({ type: ActionTypes.INIT })
源代碼中的英文注釋,已經(jīng)說(shuō)明了這一行代碼的作用。