菜单

中间件模式

相关源文件

本页面介绍在 Redux 应用程序中创建和使用中间件的常见模式和最佳实践。中间件是 Redux 中一个强大的功能,它允许在分派动作到达 reducer 之前对其进行拦截,从而实现副作用、异步操作和动作流的其他转换。

有关 Redux 中间件基本设置的信息,请参阅中间件和增强器

什么是 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 中间件模式允许分派可以执行异步操作并在完成后分派其他动作的函数。

示例实现

// 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 请求中间件

专门处理 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]

最佳实践

何时使用中间件

当您需要时使用中间件

  1. 处理副作用 - API 调用、日志记录、分析跟踪
  2. 转换动作 - 添加时间戳、ID 或来自状态的数据
  3. 支持 dispatch 的非标准输入 - 函数 (thunks)、Promise 等。
  4. 实现横切关注点 - 身份验证、错误处理等。

在编写自己的中间件之前,请考虑使用现有的中间件库

中间件类型推荐解决方案
异步逻辑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]

性能考量

  1. 避免不必要的工作 - 只处理与您的中间件相关的动作
  2. 注意中间件顺序 - 将更常用的中间件放在链中靠前的位置
  3. 使用记忆化 - 缓存结果以避免冗余处理
  4. 批量操作 - 将多个同步分派分组以减少渲染

来源:[docs/api/applyMiddleware.md:205-209], [docs/faq/Performance.md:117-138]

测试中间件

有效测试中间件

  1. 隔离测试中间件 - 传递模拟的 storenextaction 对象
  2. 验证动作的正确处理 - 检查是否分派了正确的动作
  3. 测试错误情况 - 确保错误被正确捕获和处理
  4. 使用集成测试 - 使用实际的 store 设置测试中间件

测试 thunk 中间件的示例

来源:[docs/usage/WritingTests.mdx:74-101]

中间件和 TypeScript

当将 TypeScript 与 Redux 中间件一起使用时,您应该使用 Middleware 类型

来源:[docs/usage/UsageWithTypescript.md:257-291]

结论

中间件是 Redux 中最强大的功能之一,它支持处理副作用、转换动作和扩展 Redux 功能的广泛模式。通过理解这些常见模式,您可以为复杂问题构建解决方案,同时保持 Redux 有价值的可预测性和可追溯性。

在选择和实现中间件时,请首先考虑现有解决方案,然后仅在必要时使用这些模式创建自定义中间件。精心设计的中间件可以通过集中常见关注点并使组件专注于表示逻辑来极大地简化应用程序代码。