Redux中间件(二) - 如何自己写一个中间件

前言

最近看了一下Redux的官方文档,突然感觉以前忽略了很多东西,现在回头看看,正好记录一下,并且加深印象

中间件的使用

  const store = createStore(reducers,applyMiddleware(logger));

以上是应用了redux-logger中间件的代码,只要按照官方提供的规定格式实现,并应用到中间件方法,那么,在执行一个action的时候,就会调用中间件。

在官方的示例中,有一个logger实现的示例

const logger = store => next => action =>{
    console.log('prev state',store.getState())
    console.log('dispatch',action);

    let result = next(action);

    console.log('next state',store.getState());

    return result;
}

从这个示例可以看出,实现一个中间件需要做一下几件事情:

  1. 三层函数包装:第一层传入store,第二层传入下一个中间件next,第三层传入此次执行的action;

2.在最内层的函数实现中,需要调用next中间件,并返回结果。

原理解析

首先来看一下createStore

  1. createStore(reducer, preloadedState, enhancer)
    createStore有三个参数1.reducer;2.preloadedState;3.enhancer

reducer :即一些改变state的纯函数,这个可以在官方文档查看具体定义;

preloadesState:是初始化的state,这个state可以是加载页面时从服务器提供的初始化state值,这个为服务器端渲染,并与客户端保持数据一致提供可能;

enhancer: store增强功能,在redux中特指applyMiddleware()方法的返回值;

来看看createStore方法的开头部分

if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
    enhancer = preloadedState
    preloadedState = undefined
  }

  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.')
  }

这里面第二个判断if中有enhancer为function则调用enhander(createStore)(reducer,preloadedState);我们都知道enhancer 是applyMiddleware方法的返回值,
下面在看applyMiddleware方法

  1. applyMiddleware(...middlewares)

参数即为所有要使用的符合redux的中间件;
apllyMiddleware的代码很精简

export default function applyMiddleware(...middlewares) {
  return (createStore) => (reducer, preloadedState, enhancer) => {
    const store = createStore(reducer, preloadedState, enhancer)
    let dispatch = store.dispatch
    let chain = []

    const middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    }
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

来分析一下applyMiddleware方法,

  1. 接收一个middleware数组作为参数,返回一个方法,我们暂且叫它enhancer;
  2. enhancer仍然是一个方法,他接收createStore方法作为参数,enhancer方法返回的还是一个方法,这个方法的参数与createStore方法的的签名一样,都包含三个参数,分别是reducer, preloadedState, enhancer;我们叫它mergeDispatch;
  3. mergeDispatch这个最终的方法的作用有2点,首先调用createStore创建store,然后就是不断的替换store.dispatch,以达到应用中间件的目的,大概流程如下:
Redux中间件(二) - 如何自己写一个中间件_第1张图片
QQ图片20170903151553.jpg

最终就是把原始的store.dispatch应用到所有的中间件的最核心的位置调用,其他的插件都在原始的dispatch外层包裹着。

你可能感兴趣的:(Redux中间件(二) - 如何自己写一个中间件)