1. Three common approaches in REdux

  • GetState (), which gets the tree of state objects
  • Dispatch (), which dispatches synchronized actions
  • Subscribe (), which calls the callback function when some property in the state tree changes and rerenders
/** * First, the return value of this function is an object, since it is called with store.getState(), so the return object has three attributes must be the function */
export function createStore(reducer) {
  let state  // Save the state object tree
  const listeners = []  // Save all subscribe callback functions
  state = reducer(state, {type: '@mini'})
  function getState() {
    return state
  }
  
  function dispatch(action) {
    // Replace the original state with the new state obtained by the reducer function
    state = reducer(state, action)
    // Call all subscribe callback functions to achieve the effect of re-rendering
    listeners.forEach(listener= > {
      listener()
    })
  }
  // Save all subscribe callback functions, and call all SUBSCRIBE callback functions when calling Dispatch to change the property state, to rerender the effect
  function subscribe(listener) {
    listeners.push(listener)
  }
  return {getState, dispatch, subscribe}
}
Copy the code

2. The second important thing in the Redux library is to combine reducer functions

Note that it integrates all the reducer functions and is itself a reducer. The return value of all this function is a reducer function code:

export function combineReducers(reducers) {
  
  // Because the reducer function is returned, it has state and action parameters, where state is the total state tree and action is the action passed in by Dispatch
  /** * state = { * count: 0, * msgs: [] * } */
  return function (state = {}, action) {
    // Because each reducer function is processed, the return value is the new state of the reducer function, so finally all the sub-states form a new state tree, which is used to save the new total state tree
    const newState = {}
    Because combineReducers is passed in an object, and the attribute value of each attribute is a Reducer function named after the attribute name, all keys are traversed to obtain all key names, and each key name is also the name of each reducer function
    const keys = Object.keys(reducers)
    // Iterate over the array of keys again
    keys.forEach(key= > {
      // Find the Reducer function for each child
      const childReducer = reducers[key]
      Because each function is a reducer function, we need a state object and a synchronization action, which is passed in by the user, while the substate is an attribute on the total state
      const childState = state[key]
      // Call the reducer function and return a new child state
      const newChildState = childReducer(childState, action)
      // Store the new child state into the new total state that needs to be returned at last
      newState[key] = newChildState
    })
    return newState
  }
}
Copy the code

To simplify the above code:

export function combineReducers(reducers) {
  
  return function (state = {}, action) {
    return Object.keys(reducers).reduce((newState, reducerName) = > {
      newState[reducerName] = reducers[reducerName](state[reducerName], action)
      return newState
    }, {})
  }
}
Copy the code