美文网首页饥人谷技术博客
redux中间件机制——源码解析

redux中间件机制——源码解析

作者: _贺瑞丰 | 来源:发表于2018-08-14 17:09 被阅读271次

1.中间件是在createStore函数中被作为参数传递的。

const store = createStore(
    reducer,
    applyMiddleware(sagaMiddleware)
)

2.createStore源码拆解

export default function createStore(reducer, preloadedState, enhancer) {
//- 参数位置的调整,使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.')
    }
//这里enhance就是applyMiddleware(...middleware)的执行结果
    return enhancer(createStore)(reducer, preloadedState)
  }

重点是 return enhancer(createStore)(reducer, preloadedState)
store的创建是交给了enhancer的,并且将这里定义的createStore,reducer, preloadedState等传入了enhancer中。

3.applyMiuddleware返回的是什么?

源码如下:

import compose from './compose'

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
    }
  }
}

执行applyMiuddleware返回的是一个函数:

(createStore)=>(reducer,preloadedstate,enhancer)=>{
    //获取store state,和重写dispatch方法,返回全新的store和dispatch
  return {
      ...store,
      dispatch
    }}

4.createStore中间件模式返回时调用的applymiddleware

 return enhancer(createStore)(reducer, preloadedState) === 
returrn applymiddleware(createStore)(reducer, preloadedState) 

5. 中间件拿到了createStore之后,负责创建store和重写dispatch

从源码中我们可以看到dispatch是被middlewares处理过,然后用compose拼接起来。 后面我们会举一个具体的middleware的例子

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

6. compose源码

可以看出如果参数只有1个的我时候,compose没啥用

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

  if (funcs.length === 1) {
    return funcs[0]
  }

  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}

7. 单中间件:redux-thunk

thunk接受dispatch和getState,这里是从

//在之前重写的dispatch的地方,将store原来的dispatch和getState传入了thunk中
middlewares.map(middleware => middleware(middlewareAPI))

thunk拿到了原来的dispatch和getState并重写。

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;

8.经过redux-thunk修改过的store

可以看出 dispatch现在可以接受函数了

const store = createStore(
    reducer,
    applyMiddleware(thunk)
)
console.log(store.dispatch);
dispatch函数修改后

相关文章

网友评论

    本文标题:redux中间件机制——源码解析

    本文链接:https://www.haomeiwen.com/subject/jacvbftx.html