Reux Source Learning Notes - applyMiddleware

Keywords: Javascript

When you create a store, createStore(reducer, preloadedState, enhancer), in addition to the reducer function, the initial state can also be passed into enhancer.This enhancer is used in the source code of the createStore

    return enhancer(createStore)(reducer, preloadedState)

It can accept the createStore method, make custom modifications, and then use the modified method to create the warehouse.

The only enhancer offered by redux is applyMiddleware.

applyMiddleware(...middlewares)

The main function of applyMiddleware is to override the dispatch method in createStore and to combine multiple middlewares together in a chain-like fashion without interacting with each other.This requires that middlewares follow a certain format.(getState, dispatch}) => next => action => {}

Implementation of applyMiddleware

export default function applyMiddleware(...middlewares) {
  // Returns an enhancer function that accepts createStore as an argument (as opposed to how enhancer is called)
  return createStore => (...args) => { // The enhancer function accepts reducer, preloadedState to create a warehouse
    const store = createStore(...args)
    // Custom dispatch function, dispatch is not allowed to be called when middleware is constructed
    let dispatch = () => {
      throw new Error(
        `Dispatching while constructing your middleware is not allowed. ` +
          `Other middleware would not be applied to this dispatch.`
      )
    }

    const middlewareAPI = {
      getState: store.getState, // getState function in store to get status
      dispatch: (...args) => dispatch(...args) // Custom dispatch functions
    }
    // Pass in to getState, and dispatch to middleware to generate a function in next => action => {} format
    const chain = middlewares.map(middleware => middleware(middlewareAPI))

    // Custom dispatch is updated to a combination function of multiple middleware s; the original store dispatch function is passed in to the combination function (which will act as the next function in the last middle)
    dispatch = compose(...chain)(store.dispatch)

    // Return to the store repository, where the dispatch function has been overridden to be a composite function of multiple middleware s
    return {
      ...store,
      dispatch
    }
  }
}

Combination and Chain Calls

The key is to understand that dispatch = compose (... chain) (store.dispatch), which is rewritten as a composite function of multiple middleware s.

The key sentence in the compose function is return funcs.reduce ((a, b) => (... args) => a (b (... args)).

A can be interpreted as next => action => {}, while next can be interpreted as b(...args) being the next middleware's ation => {} function.So chain call is implemented.Custom actions are done in a, calling b, and B calling c. dispatch last.

Use two middleware s as examples to comb the call process of the overridden dispatch(action).

Customize middleware

middleware must follow a certain format.(getState, dispatch}) => next => action => {}

The {getState, dispatch} parameter is passed in the const chain = middlewares.map (middleware => middleware (middlewareAPI)) part of the applyMiddleware source code, the getState of the store, and the modified dispatch.

Next is the next middleware or store.dispatch, and action is the triggered action

/*logger*/
export default ({dispatch,getState}) => next => action => {
    // Do something custom
    console.log('will dispatch ation',action);
    console.log('next in loggere',next);

    // Call the next middleware
    let returnValue = next(action);

    console.log('state after dispatch',getState());

    return returnValue;
}
/*test*/
export default ({dispatch,getState}) => next => action => {
        
    console.log('next in  test',next)

    return next(action);
}

Using applyMiddleware

store = createStore(reducer,applyMiddleware(logger,test))

When an action is triggered, the following print occurs

After the logger has done the custom action, it calls the next middleware (test) function, which is the last middleware and whose next next next is store.dispatch, triggering the action.

Posted by Waldir on Sat, 11 May 2019 16:13:53 -0700