下面介绍最后一个函数,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.
扫描二维码关注公众号,回复:
1506347 查看本文章