redux源码浅析之createStore

查看redux的包,如下


image.png

主要包括了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,管理订阅器的功能

你可能感兴趣的:(redux源码浅析之createStore)