redux 中间件原理

Redux 中间件(middleware)是 Redux 提供的一套 对 dispatch 进行增强 的机制。
它允许你在 action 被发出(dispatch)之后,到达 reducer 之前,插入你自己的逻辑。

比如:

  • 日志打印(redux-logger)

  • 处理异步(redux-thunk / redux-saga)

  • 接口请求

  • 权限判断

  • crash 处理

  • 重试机制

要理解中间件原理,只需要搞懂一句话:

核心一句话

Redux 中间件就是对 store.dispatch 的一层层包装(增强),形成类似 Koa 的洋葱模型。

一图快速理解 redux middleware 原理

action → dispatch → [middlewares...] → reducer → new state

每个中间件都能:

  • 拦截 action

  • 处理逻辑

  • 决定是否继续执行下一个中间件

  • 决定是否修改 action

  • 决定是否阻断 action

形成一个链式调用。

Redux 中间件的三层函数结构(重点)

所有中间件的签名长这样:

const middleware = store => next => action => {
  // ...你的逻辑
}

每层意义:

第一层:拿到 store
store => ...

能访问:

  • store.getState

  • store.dispatch(注意是未增强的 dispatch)

第二层:next
next => ...

next 就是:

下一个中间件的 dispatch(或者最终的 store.dispatch)

意味着:

  • 调用 next(action) 才会继续后面的中间件

  • 不调用 next 就会阻断后续流程(比如 redux-saga)

第三层:action
action => { ... }

最核心的一层,用来写你的逻辑。

中间件链是如何组成的(applyMiddleware 的核心原理)

Redux 的 applyMiddleware 会把你传入的中间件组合成一个链。

简化版源码(核心逻辑):

function applyMiddleware(...middlewares) {
  return createStore => (...args) => {
    const store = createStore(...args)
    let dispatch = store.dispatch

    const middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    }

    const chain = middlewares.map(mw => mw(middlewareAPI))

    // 洋葱模型组合
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

核心点:

  1. 对每个 middleware 调用第一层,得到第二层函数

  2. 使用 compose 做链式包装(从右向左)

  3. 得到被增强后的 dispatch

最终:

dispatch = mw1(mwAPI)(
              mw2(mwAPI)(
                mw3(mwAPI)(
                  store.dispatch)))

这样每个中间件都像一次洋葱剥皮。

洋葱模型结构(middleware 调用流程)

以 3 个中间件举例:

dispatch(action)
  |
  ↓
【middleware1】--→  next(action)
                  |
                  ↓
         【middleware2】--→ next(action)
                          |
                          ↓
                 【middleware3】--→ next(action)
                                  |
                                  ↓
                               reducer

这与 Koa 的 middleware 机制一模一样。

看一个最小的中间件例子

日志中间件:
const logger = store => next => action => {
  console.log('prev state', store.getState());
  console.log('action', action);

  const result = next(action);

  console.log('next state', store.getState());
  return result;
};

由于 next 继续执行后续逻辑,你便能打印前后状态 → 实现日志。

再看一个实现异步的中间件(redux-thunk)

const thunk = store => next => action => {
  if (typeof action === 'function') {
    return action(store.dispatch, store.getState);
  }
  return next(action);
}

如果 action 是函数:

dispatch((dispatch, getState) => {
   // 异步操作
   dispatch({ type: 'done' })
})

就能写异步逻辑,这就是 redux-thunk 的原理。

再看一个阻断式的中间件(权限控制)

const authCheck = store => next => action => {
  if (!store.getState().user.loggedIn) {
    return console.warn("Not logged in");
  }
  return next(action);
};

不调用 next,则 action 不会继续传下去。

最终总结(面试回答)

Redux middleware 是对 store.dispatch 的函数式增强,它具有三层函数结构:store => next => action => result。Redux 利用 applyMiddleware 将多个中间件组合成链(洋葱模型),每个中间件都能拦截、修改、延迟、阻断 action,从而实现日志记录、异步处理、权限控制等功能。

posted @ 2025-12-09 09:41  煜火  阅读(10)  评论(0)    收藏  举报