applyMiddleware 的使用和原理

发布于 2025-01-03 11:05:48 字数 2542 浏览 3 评论 0

使用 applyMiddleware 的两种方式,其中 todos 是容器, ['Use Redux'] 是参数, logger 是中间件

  1. 写法 1
const store = createStore(todos, ['Use Redux'], applyMiddleware(logger))
  1. 写法 2
const store =applyMiddleware(logger))(todos)(['Use Redux')

createStore 中参数 enhancer 表示中间件,也就是第三个参数。

// createStore 源码
function createStore(reducer, preloadedState, enhancer) {
    // 省略部分代码
    return enhancer(createStore)(reducer, preloadedState)
}

中间件的原理,applyMiddleware 是执行了三次,说明结构是这样的,返回两次函数

function applyMiddleware () {
  return function () {
    return function () {
      console.log('执行成功')
    }
  }
}
applyMiddleware()()()

继续深入其原理,需要了解中间件是怎么写的,中间件大概是这样的

function logger({ getState }) {
  return next => action => {
    console.log('将要提交动作', action)
    const returnValue = next(action)
    console.log('提交动作之后的状态', getState())
    return returnValue
  }
}

中间件返回两次函数,上面 logger 传入参数是代表下面的 middlewareAPI 对象,有 getStatedispatch ,和 store 不一样的。

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: (...args) => dispatch(...args)
    }
    // 中间件在这里第一次被调用
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

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

compose 方法接收所有执行过一次的中间件,虽然执行过一次,但还是函数返回函数的形式,代码 compose(...chain)(store.dispatch) 需要执行两次,注意这里不是三次

// 经过第 1 次处理
// middleware(middlewareAPI)
function applyMiddleware (middlewareAPI) {
  console.log('第一次')
  return function () {
    console.log('第二次')
    return function () {
      console.log('第三层')
    }
  }
}
// 经过第 2 次处理
// compose()
function () {
  console.log('第二次')
  return function () {
    console.log('第三层')
  }
}
// 经过第 3 次处理
// compose()()
function (store.dispatch) {
  console.log('第三层')
}

最后 dispatch 赋值的是新的函数,在第二步处理的时候,使用的是 reduce 参数的规则

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

说谎友

暂无简介

文章
评论
25 人气
更多

推荐作者

mb_TnrMmzAf

文章 0 评论 0

_1999

文章 0 评论 0

grace999

文章 0 评论 0

混浊又暗下来

文章 0 评论 0

像极了他

文章 0 评论 0

情何以堪。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文