当前位置: 代码迷 >> 综合 >> Redux源码解读--(5)createStore
  详细解决方案

Redux源码解读--(5)createStore

热度:15   发布时间:2024-01-04 23:29:15.0

下面介绍最后一个函数,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 = preloadedStatepreloadedState = 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 = reducerlet currentState = preloadedState   //当前的statelet currentListeners = []     //当前的listenerslet nextListeners = currentListenerslet isDispatching = false   //是否正在分发function ensureCanMutateNextListeners() {    //具体这里为什么会浅拷贝一个数组出来我也说不上来,有知道的麻烦帮忙解答一下if (nextListeners === currentListeners) {nextListeners = currentListeners.slice()  //只是拷贝了一份}}function getState() {  //返回当前statereturn currentState}function subscribe(listener) {if (typeof listener !== 'function') {  //监听器要是函数throw new Error('Expected listener to be a function.')}let isSubscribed = trueensureCanMutateNextListeners()  nextListeners.push(listener)return function unsubscribe() {  //返回一个函数用来解除监听if (!isSubscribed) {return}isSubscribed = falseensureCanMutateNextListeners()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) {   //不能同时执行两个dispatchthrow new Error('Reducers may not dispatch actions.')}try {isDispatching = truecurrentState = currentReducer(currentState, action)    //不论第一次传入currentState是否有值,都会根据第一次的reducer返回默认值//比如首次执行createStore就会传入一个几乎不会存在于reducer的case中的类型,这样就可以返回第一次传入reducer的默认值了。} finally {isDispatching = false   //放开dispatch入口}const listeners = currentListeners = nextListenersfor (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.