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.dispatchconst middlewareAPI = {getState: store.getState,dispatch: (action) => dispatch(action)}const chain = middlewares.map(mw => mw(middlewareAPI))// 洋葱模型组合dispatch = compose(...chain)(store.dispatch)return {...store,dispatch}}
}
核心点:
-
对每个 middleware 调用第一层,得到第二层函数
-
使用 compose 做链式包装(从右向左)
-
得到被增强后的 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,从而实现日志记录、异步处理、权限控制等功能。