美文网首页
redux 源码解析之createStore

redux 源码解析之createStore

作者: 小旎子_8327 | 来源:发表于2019-06-12 15:53 被阅读0次
    目录结构
    image.png

    工具类

    actionTypes
    isPlainObject
    waring

    src

    createStore.js:

    先看看createStore方法

    export default function createStore(reducer, preloadedState, enhancer) {……}
    

    用法举例:const store=Redux.createStore(reducers);
    第一步:参数校验
    期望:reducer、enhancer是一个function、preloadedState是个对象

     //一、如果preloadedState是个function或者多输了一个参数,报错
     if (
        (typeof preloadedState === 'function' && typeof enhancer === 'function') ||
        (typeof enhancer === 'function' && typeof arguments[3] === 'function')
      ) {
        throw new Error(
          'It looks like you are passing several store enhancers to ' +
            'createStore(). This is not supported. Instead, compose them ' +
            'together to a single function'
        )
      }
    
      //二、如果preloadedState是个function,且第三个参数enhancer未输入,则将第二个参数当作第三个参数使用
      if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
        enhancer = preloadedState
        preloadedState = undefined
      }
    
      //如果第三个参数enhancer输入,但是不是个函数,报错,如果是函数,返回enhancer的闭包调用的结果。
      if (typeof enhancer !== 'undefined') {
        if (typeof enhancer !== 'function') {
          throw new Error('Expected the enhancer to be a function.')
        }
    
        return enhancer(createStore)(reducer, preloadedState)
      }
    
     //如果reducer不是个函数,报错
      if (typeof reducer !== 'function') {
        throw new Error('Expected the reducer to be a function.')
      }
    
    

    怎么样,看起来是不是很简单!

    第二步:变量的声明与设置

      let currentReducer = reducer
      let currentState = preloadedState
      let currentListeners = []
      let nextListeners = currentListeners
      let isDispatching = false
    

    第三步:声明方法

       dispatch,
       subscribe,
       getState,
       replaceReducer,
       [$$observable]: observable
    

    dispatch:

    function dispatch(action) {
       //判断参数action是否是纯函数,不是报错
        if (!isPlainObject(action)) {
          throw new Error(
            'Actions must be plain objects. ' +
              'Use custom middleware for async actions.'
          )
        }
    
       //判断action.type 是否存在,不是报错
        if (typeof action.type === 'undefined') {
          throw new Error(
            'Actions may not have an undefined "type" property. ' +
              'Have you misspelled a constant?'
          )
        }
       
        //判断当前是否有执行其他的reducer操作
        if (isDispatching) {
          throw new Error('Reducers may not dispatch actions.')
        }
    
        //执行
        //设置isDispatching为true,防止后续的action进来触发reducer操作
        //根据action触发状态更新
        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
      }
    

    replaceReducer
    参数校验 判断参数nextReducer是不是function
    触发state更新操作

      function replaceReducer(nextReducer) {
      
        if (typeof nextReducer !== 'function') {
          throw new Error('Expected the nextReducer to be a function.')
        }
        currentReducer = nextReducer
        dispatch({ type: ActionTypes.REPLACE })
      }
    

    getState
    获取当前状态

      function getState() {
        if (isDispatching) {
          throw new Error(
            'You may not call store.getState() while the reducer is executing. ' +
              'The reducer has already received the state as an argument. ' +
              'Pass it down from the top reducer instead of reading it from the store.'
          )
        }
    
        return currentState
      }
    

    subscribe

     function subscribe(listener) {
     //参数校验 
        if (typeof listener !== 'function') {
          throw new Error('Expected the listener to be a function.')
        }
     //如果reducer正在执行,报错
     if (isDispatching) {
          throw new Error(
            'You may not call store.subscribe() while the reducer is executing. ' +
              'If you would like to be notified after the store has been updated, subscribe from a ' +
              'component and invoke store.getState() in the callback to access the latest state. ' +
              'See https://redux.js.org/api-reference/store#subscribe(listener) for more details.'
          )
        }
    
        let isSubscribed = true
    
        ensureCanMutateNextListeners()
        nextListeners.push(listener)
    
        return function unsubscribe() {
          if (!isSubscribed) {
            return
          }
    
          if (isDispatching) {
            throw new Error(
              'You may not unsubscribe from a store listener while the reducer is executing. ' +
                'See https://redux.js.org/api-reference/store#subscribe(listener) for more details.'
            )
          }
    
          isSubscribed = false
    
          ensureCanMutateNextListeners()
          const index = nextListeners.indexOf(listener)
          nextListeners.splice(index, 1)
        }
      }
    

    相关文章

      网友评论

          本文标题:redux 源码解析之createStore

          本文链接:https://www.haomeiwen.com/subject/rtylfctx.html