查看redux的包,如下
主要包括了6个文件,其中的index是将另外五个导出
export {
createStore,
combineReducers,
bindActionCreators,
applyMiddleware,
compose
}
1.createStore
- 1.1 容错代码
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
enhancer = preloadedState
preloadedState = undefined
}
这是一段容错代码,就是传两个参数和三个参数的区别,传两个参数时,判断第二个参数是不是方法,如果是,把它当增强器处理
第二段代码
- 1.2 增强器处理(直接可以理解为middleware)
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
return enhancer(createStore)(reducer, preloadedState)
}
if (typeof reducer !== 'function') {
throw new Error('Expected the reducer to be a function.')
}
这段主要做的是,如果有增强器,那么去执行增强器
这里需要注意的是:此处的增强器,一般是middleWare,会把createStore和reducer和初始化状态传给中间件,比如我们查看redux-thunk的代码,它里面重新创建了createStore
- 1.3 变量声明
let currentReducer = reducer
let currentState = preloadedState
let currentListeners = []
let nextListeners = currentListeners
let isDispatching = false
声明了一些需要的变量
- 1.4 数组拷贝方法
function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice()
}
}
- 1.5 getState
function getState() {
return currentState
}
- 1.6 订阅者
function subscribe(listener) {
if (typeof listener !== 'function') {
throw new Error('Expected listener to be a function.')
}
let isSubscribed = true
ensureCanMutateNextListeners()
nextListeners.push(listener)
return function unsubscribe() {
if (!isSubscribed) {
return
}
isSubscribed = false
ensureCanMutateNextListeners()
const index = nextListeners.indexOf(listener)
nextListeners.splice(index, 1)
}
}
它的目的就是给用户自己新增订阅器,当disptach时,去触发这些订阅器,并且返回了一个删除该订阅器的一个方法
- 1.7 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
}
const listeners = currentListeners = nextListeners
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
listener()
}
return action
}
来分析下dispatch,看看它做了啥,前面两个if,对action做了限制
- 1.7.1 限制了action必须是一个简单对象,这里用到了lodash中的方法isPlainObject,可以参考官网,一般使用{}或者object.create创建的都算简单对象
- 1.7.2 action.type必须有
try模块使用reducer更新了state
listener就是触发了订阅器的代码 - 1.8 replaceReducer
function replaceReducer(nextReducer) {
if (typeof nextReducer !== 'function') {
throw new Error('Expected the nextReducer to be a function.')
}
currentReducer = nextReducer
dispatch({ type: ActionTypes.INIT })
}
由代码来看,仅仅是替换了以下reducer
- 1.9 observable
这个我在项目中几乎没用到,暂时过
最后,createStore之后,dispatch init了以下
结论
由代码分析可知,其实createStore做的事情,主要是实现middle的引用,以及定义了dispatch,getState,管理订阅器的功能