redux中间件探秘

从redux-thunk引出思索

在运用redux-thunk举行异步action誊写的时刻,我常常猎奇redux究竟如何运作,让asyncAction成为可以

为了探讨,我们必需看一下redux-thunk的源码了。荣幸的是redux-thunk的源码很少。。。至于为何,下面立马解说。

redux-thunk的源码

// redux-thunk source code
function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }

    return next(action);
  };
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

从源码可以看出该中间件仅仅只是一个工场函数,输出了一个嵌套工场函数的工场函数,谁人终究参数带着next的返回函数,就是redux所须要顺应的中间件。

以es6箭头语法看来可以比较贫苦,我们可以试着把这个代码直接转成es5的情势看看。

function createThunkMiddleware(extraArgument) {
  return function (storeOrFakeStore) {
    var dispatch = storeOrFakeStore.dispatch;
    var getState = storeOrFakeStore.getState;
    return function (next) {
      return function (action) {
          return action(dispatch, getState, extraArgument);
      }
      return next(action);
    }
  };
}

从这个源码可以看出,自身中间件是会接收当前store或许一个fakeStore(这个fakeStore可以仅仅只承载了store的两个api,dispatch和getState),并将dispatch和getState这两个store的要领传进可以实行异步操纵的action函数里。如许,action完成异步操纵今后,一样被给予了dispatch的权益,就可以将状况经由过程action流转到下一个场景了。

那同学们又会问了,这个next是个啥?恩,实在这个next实在就是下一个要处置惩罚action的中间件,毕竟中间件是一个接着一个的对吧。假如人人写过koa或许express应当对这个next会熟习许多。

接下来我们来看看react源码中的createStore模块是如何运用中间件的。

我们运用createStore api建立store的时刻发生了什么

applyMiddleware一样也是一个工场,假如读者您用过redux中间件的话,你应当晓得redux建立store是如何建立的

const store = createStore(
  reducer,
  applyMiddleware(...middleware)
)

以下是createStore的源码,我们只看相干的一部分

export default function createStore(reducer, preloadedState, enhancer) {
  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)
  }
  ...
}

连系store的声明和运用,我们可以晓得redux的第三个参数可以接收一个叫做加强器的东西,假如存在加强器,则直接挪用加强器要领,返回新的store并加强redux的功用。而运用中间件的时刻,redux将存在的applyMiddleware工场要领作为加强器运用在了redux上。

applyMiddleware api如何完成中间件操纵的。

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工场函数对传入的中间件举行了compose操纵,使中间件相互之间呈嵌套的情势,如许在中间件里的next函数就可以next()实行下去了。。。新的dispatch会从第一个中间件最先触发,如许,在我们挪用store.dispatch的时刻,就会将中间件走一遍了。

// compose函数
export default function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }

  if (funcs.length === 1) {
    return funcs[0]
  }
  // 假如存在多个中间件,直接运用reduce要领将各个中间件嵌套起来。
  // 因而我们在运用中间件的时刻就要注重了,中间件实质是一个阻拦操纵
  // 假如我们有两个中间件对某一个范例的action前后做了阻拦,我们必需注重
  // 在createStore的时刻插进去中间件的递次,中间件要领的实行是有序的。
  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}

你也可以制造一个中间件

如何,redux的源码简朴吗?简朴到同学们也能本身开辟中间件,如今人人本身也可以动手写本身的react中间件了。

    原文作者:有把但没什么卵用
    原文地址: https://segmentfault.com/a/1190000010433373
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞