createStore几乎囊括了Redux的核心功能。
参数归一化
先看看createStore的函数签名:
export default function createStore(reducer, initialState, enhancer) {
// ...
}
前两个参数比较常见,那么enhancer扮演了什么角色呢?
if (typeof initialState === 'function' && typeof enhancer === 'undefined') {
enhancer = initialState
initialState = undefined
}
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
return enhancer(createStore)(reducer, initialState)
}
在enhancer(createStore)(reducer, initialState)调用中,enhancer对createStore的能力进行了增强,最终返回store。
典型使用案例是redux-devtools-extension,它将Redux DevTools做成浏览器插件。
初始状态及getState
完成基本参数校验后,在createStore中声明了如下变量及getState方法
var currentReducer = reducer
var currentState = initialState
var currentListeners = []
var nextListeners = currentListeners
var isDispatching = false
function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice()
}
}
function getState() {
return currentState
}
- currentReducer:当前的reducer,支持通过store.replaceReducer方式动态替换reducer,为代码热替换提供了可能。
- currentState:应用的当前状态,默认为初始化时的状态。
- currentListeners、nextListeners:监听器
- isDispatching:某个action是否处于分发的处理过程中
getState方法用于返回当前状态。
subscribe、unsubscribe
在getState之后定义了store的subscribe方法
function subscribe(listener) {
if (typeof listener !== 'function') {
throw new Error('Expected listener to be a function.')
}
var isSubscribed = true
ensureCanMutateNextListeners()
nextListeners.push(listener)
return function unsubscribe() {
if (!isSubscribed) {
return
}
isSubscribed = false
ensureCanMutateNextListeners()
var index = nextListeners.indexOf(listener)
nextListeners.splice(index, 1)
}
}
subscribe将listener添加到nextListeners中,unsubscribe可以删除这个listener。
dispatch
接下来就是dispatch
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.')
}
try {
isDispatching = true
currentState = currentReducer(currentState, action)
} finally {
isDispatching = false
}
var listeners = currentListeners = nextListeners
for (var i = 0; i < listeners.length; i++) {
listeners[i]()
}
return action
}
先是一些校验,然后将当前的状态和action传给当前的reducer,用于生成最新的state。再依次调用所有的监听器,通知状态的变更。最后返回action
replaceReducer
这个方法主要用于reducer的热替换,在开发过程中很少使用
function replaceReducer(nextReducer) {
if (typeof nextReducer !== 'function') {
throw new Error('Expected the nextReducer to be a function.')
}
currentReducer = nextReducer
dispatch({ type: ActionTypes.INIT })
}
dispatch({ type: ActionTypes.INIT })是为了拿到所有reducer中的初始状态,只用所有状态都成功获取后,Redux应用才能有条不紊地运作。
注:redux源码版本v3.5.2
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。