Redux applyMiddleware 原理剖析

本文深入剖析Redux的applyMiddleware机制,解释如何通过middleware拦截并处理action。middleware提供了一个处理action的扩展点,允许在action到达reducer之前进行操作。文中通过实例解释了applyMiddleware的源码、compose函数的应用,以及dispatch流程,帮助读者理解store.dispatch如何层层调用middleware并执行相应的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redux applyMiddleware 原理剖析

 

最近在总结最近用的知识,好记性不如烂笔头,所以写出来记录下。

“It provides a third-party extension point between dispatching an action, and the moment it reaches the reducer.” 
这是 Dan Abramov 对 middleware 的描述。它提供了一个分类处理 action 的机会。在 middleware 中,你可以检阅每一个流过的 action,挑选出特定类型的 action 进行相应操作,给你 一次改变 action 的机会。

应用 middleware 后 Redux 处理事件的逻辑

我们还是从实际出发,再来看下内部构造:

 

打印日志中间件

白名单中间件

applyMiddleware中间件的源码非常精炼,大约只有20多行。

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

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

    return {
      ...store,
      dispatch
    }
  }
}

 

看懂这段代码,需要提前了解函数式编程compose以及pipe思想,其实就是一个传参数据流,一个从右到左一个从左到右。我们带着问题去看这段代码,为什么我们平时写的时候要传入(store) => (next) => (action)这三个参数?

代码前几行创建了store,createStore后面三个参数是Redux原生createStore方法的标准参数。下面的middlewareAPI其实就是一个精简的store,并且提供了getState和dispach方法。

接下来来看compose,compose顾英文名思中国义即组合函数,将多个函数组合起来串联执行,一个函数的输出作为另一个函数的输入,一旦第一个函数开始执行,过程就会像多米诺骨牌。

let result = compose(f1, f2, f3, f4)(value); ====> let result = f1(f2(f3(f4(value))));

 chain = middlewares.map(middleware => middleware(middlewareAPI))
 dispatch = compose(...chain)(store.dispatch)

dispatch = compose(...chain)(store.dispatch)

可以变化为:

fnMiddle = fn(middlewareAPI);

dispatch = fnMiddle(store.dispatch)

最后等价于:

dispatch = fn(middlewareAPI)(store.dispatch)

接着:
store.dispatch(action) 
等价于
fn(middlewareAPI)(store.dispatch)(action) == 对应middleware的三个参数store, next, action。

dispatch = compose(...chain)(store.dispatch) === dispatch= fn1Middle(fn2Middle(store.dispatch))

// fn1Middle = fn1(middlewareAPI)

首先执行的是fn2Middle(store.dispatch),返回结果是如下的一个函数。紧接着fn1Middle( (action) => {} ),这个action函数相当于占据了fn1中next参数的位置。在收到action参数之前呢函数并不会执行。

// fn2Middle(store.dispatch)执行后
(action) => {
    ....
    next(action)
    ....
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值