本页面介绍在 Redux 应用程序中创建和使用中间件的常见模式和最佳实践。中间件是 Redux 中一个强大的功能,它允许在分派动作到达 reducer 之前对其进行拦截,从而实现副作用、异步操作和动作流的其他转换。
有关 Redux 中间件基本设置的信息,请参阅中间件和增强器。
Redux 中间件在分派动作和动作到达 reducer 之间提供了一个第三方扩展点。中间件围绕 store 的 dispatch 方法形成一个管道,允许您以超越 reducer 支持的同步更新的方式处理动作。
来源:[docs/api/applyMiddleware.md:14-16], [docs/api/Store.md:56-61]
Redux 中间件使用三重嵌套函数结构编写,通常被称为“柯里化”
签名如下所示
({ getState, dispatch }) => next => action => { /* middleware logic */ }
这种柯里化模式允许中间件函数的轻松组合,并创建处理步骤的管道。
来源:[docs/api/applyMiddleware.md:30-31], [docs/faq/DesignDecisions.md:68-83]
日志中间件是最简单的示例之一,用于记录动作和状态更改以进行调试。
示例实现
const logger = store => next => action => {
console.log('dispatching', action)
const result = next(action)
console.log('next state', store.getState())
return result
}
来源:[docs/api/applyMiddleware.md:44-67]
thunk 中间件模式允许分派可以执行异步操作并在完成后分派其他动作的函数。
示例实现
// Thunk middleware
const thunk = ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState)
}
return next(action)
}
// Thunk action creator
const fetchUser = (id) => async (dispatch, getState) => {
dispatch({ type: 'FETCH_USER_STARTED' })
try {
const response = await api.fetchUser(id)
dispatch({ type: 'FETCH_USER_SUCCESS', payload: response.data })
} catch (error) {
dispatch({ type: 'FETCH_USER_FAILURE', error })
}
}
来源:[docs/api/applyMiddleware.md:73-202], [docs/usage/UsageWithTypescript.md:257-291]
专门处理 API 请求的中间件可以集中请求逻辑和错误处理
来源:[docs/faq/CodeStructure.md:154-165]
用于捕获和处理动作处理管道中发生的错误的中间件
来源:[docs/usage/WritingCustomMiddleware.md:16-22]
仅在特定环境或条件下应用的中间件
示例
// Only apply logging in development
const conditionalLogger = ({ getState }) => next => action => {
if (process.env.NODE_ENV !== 'production') {
console.log('dispatching', action)
}
const result = next(action)
if (process.env.NODE_ENV !== 'production') {
console.log('next state', getState())
}
return result
}
来源:[docs/api/applyMiddleware.md:212-227]
在将动作传递给 reducer 之前修改它们的中间件
来源:[docs/usage/WritingCustomMiddleware.md:119-138]
允许一次分派多个动作以减少重新渲染的中间件
来源:[docs/faq/Performance.md:117-138]
当您需要时使用中间件
在编写自己的中间件之前,请考虑使用现有的中间件库
| 中间件类型 | 推荐解决方案 |
|---|---|
| 异步逻辑 | Redux Thunk, Redux Saga, RTK Query |
| 日志记录 | redux-logger |
| 分析 | redux-segment, redux-analytics |
| 批处理 | redux-batched-actions, redux-batch |
来源:[docs/usage/WritingCustomMiddleware.md:29-40], [docs/faq/Actions.md:110-123]
来源:[docs/api/applyMiddleware.md:205-209], [docs/faq/Performance.md:117-138]
有效测试中间件
store、next 和 action 对象测试 thunk 中间件的示例
来源:[docs/usage/WritingTests.mdx:74-101]
当将 TypeScript 与 Redux 中间件一起使用时,您应该使用 Middleware 类型
来源:[docs/usage/UsageWithTypescript.md:257-291]
中间件是 Redux 中最强大的功能之一,它支持处理副作用、转换动作和扩展 Redux 功能的广泛模式。通过理解这些常见模式,您可以为复杂问题构建解决方案,同时保持 Redux 有价值的可预测性和可追溯性。
在选择和实现中间件时,请首先考虑现有解决方案,然后仅在必要时使用这些模式创建自定义中间件。精心设计的中间件可以通过集中常见关注点并使组件专注于表示逻辑来极大地简化应用程序代码。