下面介绍最后一个函数,CreateStore.先上一个基本的用法吧。
const store = createStore(reducers, state, enhance);这个enhance就是 applyMiddleware(...middleware),可以参见 上一篇。
下面上源码吧。首先说一下,这么多代码其实首次执行的逻辑很简单,大部分代码都是定义了一个函数去等待调用的,真正就只是调用了一个默认的dispatch方法,初始化了一下下currentState.
export default function createStore(reducer, preloadedState, enhancer) {
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') { //第一步操作表明,可以不传第二个参数,如果不传则置为undefined,将enhancer过渡到第三个参数
enhancer = preloadedState
preloadedState = undefined
}
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') { //enhancer必须为函数
throw new Error('Expected the enhancer to be a function.')
}
return enhancer(createStore)(reducer, preloadedState) //如果传递enhancer,则把createStore作为参数传递过去,我在上一篇说过,第三个参数不传也可以,因为这里根本就不会接收!applymiddleware中会将createStore执行并返回。
}
if (typeof reducer !== 'function') {
throw new Error('Expected the reducer to be a function.')
}
let currentReducer = reducer
let currentState = preloadedState //当前的state
let currentListeners = [] //当前的listeners
let nextListeners = currentListeners
let isDispatching = false //是否正在分发
function ensureCanMutateNextListeners() { //具体这里为什么会浅拷贝一个数组出来我也说不上来,有知道的麻烦帮忙解答一下
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice() //只是拷贝了一份
}
}
function getState() { //返回当前state
return currentState
}
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) //从listeners中去除
}
}
function dispatch(action) {
if (!isPlainObject(action)) { //action必须是个对象{type:'XXX'}
throw new Error(
'Actions must be plain objects. ' +
'Use custom middleware for async actions.'
)
}
if (typeof action.type === 'undefined') { //对象必须有type属性(唯一确定一个action,不能重复)
throw new Error(
'Actions may not have an undefined "type" property. ' +
'Have you misspelled a constant?'
)
}
if (isDispatching) { //不能同时执行两个dispatch
throw new Error('Reducers may not dispatch actions.')
}
try {
isDispatching = true
currentState = currentReducer(currentState, action) //不论第一次传入currentState是否有值,都会根据第一次的reducer返回默认值
//比如首次执行createStore就会传入一个几乎不会存在于reducer的case中的类型,这样就可以返回第一次传入reducer的默认值了。
} finally {
isDispatching = false //放开dispatch入口
}
const listeners = currentListeners = nextListeners
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
listener() //将监听器执行一遍
}
return action
}
function replaceReducer(nextReducer) {
if (typeof nextReducer !== 'function') {
throw new Error('Expected the nextReducer to be a function.')
}
currentReducer = nextReducer //更换当前的reducer,并且执行默认dispatch返回默认值。
dispatch({ type: ActionTypes.INIT })
}
//由于一个正规的reducer都会返回一个默认值,执行这一步(ActionTypes真的很少会被定义),为了返回reducer的默认值。
dispatch({ type: ActionTypes.INIT })
return {
dispatch,
subscribe,
getState,
replaceReducer
}
}
大概源码就这些,通过上一篇我们可以发现这个middleware是可以compose的,也就是说可以组合,来达到强化dispatch的目的。那么是不是可以通过compose这个applymiddleware来做些什么呢?
提升:
我们发现在createStore中并没有直接说applymiddleware,而是使用了enhancer这个名词,增强器。
那么我就认为applymiddleware其实是一个增强器,那肯定不止这一个喽。比如:
const store = createStore(combineReducers({ routering: routerReducer }),
{},
composeEnhancers( //这个函数也是一个类库中引用的
applyMiddleware(myTestMidware_delay, ...middleware,myTestMidware),
myEhancer
)
);
还是那个compose的套路,
我传递的参数是createStore这个函数,他返回一个createStore函数,然后在下一个函数中把上一个传入的createStore执行一下,这就是我们要做的。这里增强的是createStore这个函数。
const myEhancer = (createstore)=> (reducer, preloadedState) => {
const store = createstore(reducer, preloadedState); //接收返回的store,并继续增强。
const dispatch = (action)=>{
console.log('我是一个Enhancer,action为:',action);
return store.dispatch(action);
}
return {...store,dispatch};
}
由于createStore不止执行性的操作,所以这里的return 不可以省略,每次返回的都是自己增强过的store。
通过增强器也可以达到增强dispatch的效果,所以能通过middleware实现的,都可以通过enhancer实现。
最后,谁知道那个ensureCanMutateNextListeners是干嘛的啊,留言,thx.