Redux中Middleware原理

Redux中Middleware原理

下面以redux-trunk为示例了解applyMiddleware用于干什么。

redux-thunk/src/index.js

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;

首先由上面代码可以看出trunk是一个({ dispatch, getState }) =>{}这样的箭头函数。

当 applyMiddleware(trunk)执行后,:

redux/src/applyMiddleware.js

export default function applyMiddleware(...middlewares) {
  return createStore => (...args) => {
    const store = createStore(...args)
    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,
      dispatch: (...args) => dispatch(...args)//此处的args不是上面的args
    }
    const chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

从applyMiddleware函数可知返回也是一个函数,trunk作为上一级参数middlewares这个闭包数组中的一个项。

现在我们进入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.')
    }
	//此时enhancer增强函数是applyMiddleware返回的函数
	//reducer是函数,preloadedState现在是undefined
    return enhancer(createStore)(reducer, preloadedState)
  }

传入参数发现const store = createStore(…args)传入reducer新建了一个store,并创建了middlewareAPI中的两个属性,记住dispatch函数中的args不是外面的args,不要混淆。

trunk中传入这个对象返回 next=>{}这个函数,那么chain现在就是这个函数。进入compose函数运算后返回next=>{}函数本身,再次计算后返回action=>{}这个函数,也就是说dispatch函数就是action=>{}这个函数。

总结:

(1)action=>{}函数中的next指的是store.dispatch;

(2)createStore()有中间件后返回的dispatch不是没有传入中间件的dispatch,而是action=>{}函数,store的dispatch是作为next闭包变量传入的;

(3)由createThunkMiddleware函数可知,当action为函数时执行action(dispatch, getState, extraArgument);需注意,此处的dispatch不是store的dispatch,而是applyMiddleware中声明的dispatch,由于dispatch = compose(…chain)(store.dispatch)重新定义了dispatch(引用数据类型,内存指向一样),所以在action中传入的dispatch在执行时执行的是middlewareAPI的dispatch,执行时调用next(createStore中的dispatch方法);

(4)在异步处理的情况下,action无法通过import来获取store的dispatch方法(action中此时store未建立),通过中间件的方式将store中的dispatch方法传递给闭包来保存并实现异步触发。

你可能感兴趣的:(React)