React 中间件(通常指 Redux 中间件)的核心作用是增强 dispatch
方法,使其能够处理异步操作或添加日志等附加功能
一、中间件原理
1. 核心目标
- 扩展
dispatch
功能 :允许dispatch
接收函数(如异步 Action)或其他非普通 Action 对象。 - 保持单向数据流 :中间件在调用
next(action)
后仍需将控制权交还给 Redux 流程。
2. 中间件签名
typescript
type MiddlewareAPI<S = any, A extends Action = Action> = {
dispatch: Dispatch<A>; // 原始 dispatch 方法
getState: () => S; // 获取当前状态
};
type Middleware<S = any, A extends Action = Action> = (
api: MiddlewareAPI<S, A>
) => (next: Dispatch<A>) => Dispatch<A>;
- **
MiddlewareAPI
**:提供dispatch
和getState
的访问权限。 - 中间件工厂函数 :接收
MiddlewareAPI
,返回一个增强后的dispatch
函数。
3. 中间件链式调用
多个中间件通过 柯里化 组合成一个"洋葱模型":

执行顺序:
Action → Middleware1 → Middleware2 → ... → 原始 dispatch → Reducer → 更新 State → 反向通知 Middleware
二、TypeScript 实现
1. 定义类型
typescript
type Action = { type: string };
type Dispatch = (action: Action) => void;
type GetState = () => any;
type MiddlewareAPI = { dispatch: Dispatch; getState: GetState };
type Middleware = (api: MiddlewareAPI) => (next: Dispatch) => Dispatch;
type Reducer<S> = (state: S, action: Action) => S;
2. 应用中间件(applyMiddleware)
typescript
// applyMiddleware 函数实现
function applyMiddleware(...middlewares: Middleware[]): (createStore: typeof createStore) => typeof createStore {
return (createStore) => (reducer, initialState) => {
// 创建原始 store
const store = createStore(reducer, initialState);
// 创建中间件 API
const middlewareAPI: MiddlewareAPI = {
getState: store.getState,
dispatch: (action) => store.dispatch(action)
};
// 给每个中间件注入 middlewareAPI,得到新的 dispatch 函数
const chain = middlewares.map(middleware => middleware(middlewareAPI));
// 组合所有中间件的 dispatch 函数
let enhancedDispatch = chain.reduceRight((next, middleware) => middleware(next), store.dispatch);
// 返回一个新的 store 对象,替换原来的 dispatch
return {
...store,
dispatch: enhancedDispatch
};
};
}
3. 完整代码
ts
// 定义类型
type Action = { type: string };
type Dispatch = (action: Action) => void;
type GetState = () => any;
type MiddlewareAPI = { dispatch: Dispatch; getState: GetState };
type Middleware = (api: MiddlewareAPI) => (next: Dispatch) => Dispatch;
type Reducer<S> = (state: S, action: Action) => S;
// createStore 函数实现
function createStore<S>(
reducer: Reducer<S>,
initialState: S,
enhancer?: (createStore: typeof createStore) => typeof createStore
): { dispatch: Dispatch; subscribe: (listener: () => void) => () => void; getState: GetState } {
// 如果有 enhancer,则应用它
if (enhancer) {
return enhancer(createStore)(reducer, initialState);
}
let state = initialState;
const listeners: (() => void)[] = [];
// 获取当前状态
const getState: GetState = () => state;
// 分发 action
const dispatch: Dispatch = (action) => {
state = reducer(state, action);
// 通知所有订阅者
listeners.forEach(listener => listener());
};
// 订阅状态变化
const subscribe = (listener: () => void) => {
listeners.push(listener);
// 返回取消订阅的函数
return () => {
const index = listeners.indexOf(listener);
if (index !== -1) {
listeners.splice(index, 1);
}
};
};
// 初始化状态
dispatch({ type: '@@INIT' });
return { dispatch, subscribe, getState };
}
// applyMiddleware 函数实现
function applyMiddleware(...middlewares: Middleware[]): (createStore: typeof createStore) => typeof createStore {
return (createStore) => (reducer, initialState) => {
// 创建原始 store
const store = createStore(reducer, initialState);
// 创建中间件 API
const middlewareAPI: MiddlewareAPI = {
getState: store.getState,
dispatch: (action) => store.dispatch(action)
};
// 给每个中间件注入 middlewareAPI,得到新的 dispatch 函数
const chain = middlewares.map(middleware => middleware(middlewareAPI));
// 组合所有中间件的 dispatch 函数
let enhancedDispatch = chain.reduceRight((next, middleware) => middleware(next), store.dispatch);
// 返回一个新的 store 对象,替换原来的 dispatch
return {
...store,
dispatch: enhancedDispatch
};
};
}
三、完整使用示例
1. 创建增强后的 Store
typescript
// logger 中间件实现
const loggerMiddleware: Middleware = (api) => (next) => (action) => {
console.log('dispatching', action);
const result = next(action);
console.log('next state', api.getState());
return result;
};
// thunk 中间件实现
const thunkMiddleware: Middleware = (api) => (next) => (action) => {
// 如果 action 是函数,则调用它,并传入 dispatch 和 getState
if (typeof action === 'function') {
return action(api.dispatch, api.getState);
}
// 否则,正常分发 action
return next(action);
};
// 示例 reducer
function counterReducer(state: number = 0, action: Action): number {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}
// 测试代码
function testRedux() {
// 创建带有中间件的 store
const store = applyMiddleware(thunkMiddleware, loggerMiddleware)(createStore)(counterReducer, 0);
// 订阅状态变化
const unsubscribe = store.subscribe(() => {
console.log('state changed:', store.getState());
});
// 分发普通 action
store.dispatch({ type: 'INCREMENT' });
// 分发 thunk action
store.dispatch((dispatch, getState) => {
console.log('thunk action start, current state:', getState());
dispatch({ type: 'INCREMENT' });
dispatch({ type: 'INCREMENT' });
console.log('thunk action end');
});
// 分发普通 action
store.dispatch({ type: 'DECREMENT' });
// 取消订阅
unsubscribe();
}
// 运行测试
testRedux();
四、关键设计解析
-
中间件执行顺序
applyMiddleware
从右到左组合中间件(类似函数组合f(g(h(dispatch)))
),但实际调用时从左到右执行(洋葱模型)。 -
Thunk 中间件原理
通过检查
action
是否为函数,支持异步操作:typescriptif (typeof action === 'function') { action(dispatch, getState); // 允许在函数内分发多个 Action }
-
类型安全
Dispatch
类型扩展为支持函数 Action。- 中间件工厂函数严格约束
MiddlewareAPI
和next
的类型。
五、与 React-Redux 的关联
React-Redux 的 connect
或 Hooks(如 useDispatch
)内部会使用 Redux 的 dispatch
,因此中间件对 React 组件透明。开发者只需关注:
- 普通 Action:
dispatch({ type: 'INCREMENT' })
- 异步 Action:
dispatch(async (dispatch) => { ... })
六、总结
-
中间件本质 :通过包装
dispatch
方法,在 Action 到达 Reducer 前插入逻辑。 -
典型中间件:
redux-thunk
:处理异步 Action(函数)。redux-logger
:记录日志。redux-saga
:基于 Generator 的复杂副作用管理(需更高级实现)。