Redux源码解读--(5)createStore

下面介绍最后一个函数,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.




猜你喜欢

转载自blog.csdn.net/run_youngman/article/details/79088786
今日推荐