The directory structure

Utility class actionTypes isPlainObject Waring

createStore.js:

Look at the createStore method first

Export default function createStore(Reducer, preloadedState, enhancer) {...... }Copy the code

Const store= redux.createstore (reducers);

Step 1: parameter verification

Expectations: Reducer, enhancer are a function and preloadedState is an object

// If preloadedState is a function or one more parameter is entered, An error 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')} Use if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {enhancer = PreloadedState preloadedState = undefined} // If the third parameter is entered, but it is not a function, an error is reported. If it is a function, the result of the enhancer closure is returned. if (typeof enhancer ! == 'undefined') { if (typeof enhancer ! == 'function') { throw new Error('Expected the enhancer to be a function.') } return enhancer(createStore)(reducer, PreloadedState)} // If reducer is not a function, error if (typeof reducer! == 'function') { throw new Error('Expected the reducer to be a function.') }Copy the code

How about that? Doesn’t that look easy!

Step 2: Declare and set variables

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

Step 3: Declare methods

   dispatch,
   subscribe,
   getState,
   replaceReducer,
   [$$observable]: observable
Copy the code

dispatch

Function dispatch(action) {// If (! isPlainObject(action)) { throw new Error( 'Actions must be plain objects. ' + 'Use custom middleware for async actions.' } // Check whether action.type exists. 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.')} // Run the reducer operation // Set isDispatching to true, Try {isDispatching = true currentState = currentReducer(currentState, Action)} finally {isDispatching = false} Listeners = (currentListeners = nextListeners) for (let I = 0; i < listeners.length; Listener = listeners[I] listener()}Copy the code

replaceReducer

Parameter verification Checks whether function triggers the state update

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

getState

Get the current state

  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
  }
Copy the code

subscribe

Function subscribe(listener) {// Check if (typeof listener! == 'function') {throw new Error('Expected the listener to be a function.')} 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) } }Copy the code