菜单

React-Redux Hooks

相关源文件

React-Redux Hooks | reduxjs/redux | DeepWiki

React-Redux Hooks 概述

React-Redux hooks 为 React 组件提供了一种与 Redux store 交互的现代方式,无需使用旧版的高阶组件方法。这些 hooks 在 React-Redux v7.1.0 中引入,现在是 React 中使用 Redux 的推荐方式。

来源: docs/tutorials/fundamentals/part-5-ui-and-react.md92-159

核心 React-Redux Hooks

useSelector Hook

useSelector hook 允许 React 组件从 Redux store 读取数据。它将一个 selector 函数作为参数,并从 store state 返回选定的值。

useSelector 的主要特点

  • 自动订阅:当组件挂载时,它会自动订阅 Redux store。
  • 自动取消订阅:当组件卸载时,它会自动取消订阅。
  • 重新渲染:当 action 被 dispatch 时,useSelector 会用更新后的 state 再次运行你的 selector 函数。如果 selector 结果与之前不同(使用严格的 === 比较),组件会重新渲染。

基本用法

来源: docs/tutorials/fundamentals/part-5-ui-and-react.md132-227 docs/usage/UsageWithTypescript.md375-409

useDispatch Hook

useDispatch hook 让你的组件可以访问 Redux store 的 dispatch 方法,从而可以 dispatch actions。

基本用法

来源: docs/tutorials/fundamentals/part-5-ui-and-react.md227-239 docs/usage/UsageWithTypescript.md410-419

<Provider> 组件

虽然不是 hook,但 Provider 组件对于使用 React-Redux hooks 至关重要。它使 Redux store 可供任何需要访问它的嵌套组件使用。

Provider 必须放置在组件树的周围,通常在应用程序的顶层。

来源: docs/tutorials/fundamentals/part-5-ui-and-react.md279-317

有效使用 Hooks

组件中的多个 Selector

你可以在一个组件中多次调用 useSelector 来选择不同的 state 片段。每次调用都会创建对 Redux store 的独立订阅。

来源: docs/tutorials/fundamentals/part-5-ui-and-react.md360-418

优化性能

避免不必要的重新渲染

由于 useSelector 使用严格相等 (===) 来判断是否需要重新渲染,因此从 selector 返回新的对象或数组引用可能会导致不必要的重新渲染。一些解决方案包括:

  1. 在可能的情况下选择原始值
  2. shallowEqual 比较器作为第二个参数传递给 useSelector
  3. 使用 Reselect 等库创建 memoized selector

来源: docs/tutorials/fundamentals/part-5-ui-and-react.md420-534 docs/faq/ReactRedux.md85-119

本地组件状态 vs Redux 状态

并非所有状态都需要保存在 Redux 中。对于以下情况,请使用本地组件状态(通过 useStateuseReducer):

  • 表单输入值
  • UI 状态,例如“下拉菜单是否打开”
  • 任何仅由单个组件需要的数据

Redux 用于:

  • 多个组件之间需要的数据
  • 组件卸载后需要缓存的数据
  • 需要时间旅行调试的数据

来源: docs/tutorials/fundamentals/part-5-ui-and-react.md331-359 docs/faq/OrganizingState.md25-39

TypeScript 集成

将 TypeScript 与 React-Redux hooks 结合使用可提供更好的类型安全和开发者体验。

定义 Root State 和 Dispatch 类型

首先,定义 Redux store state 和 dispatch 函数的类型

来源: docs/usage/UsageWithTypescript.md49-75

创建类型化 Hooks

创建具有正确类型的预类型化 hooks 版本

这是 React Redux v9.1.0 的推荐方法,该版本添加了 .withTypes() 方法以简化类型化过程。

来源: docs/usage/UsageWithTypescript.md77-117 examples/counter-ts/src/app/hooks.ts1-6

在组件中使用类型化 Hooks

然后在组件中使用这些预类型化的 hooks

这种方法在整个 Redux 交互中提供了类型安全

  1. selector 函数获得正确的状态类型
  2. dispatch 函数了解 thunk 和其他中间件

来源: docs/usage/UsageWithTypescript.md188-205

常见模式和最佳实践

创建可复用 Selectors

创建可复用的 selector 函数来提取特定的 state 片段

处理列表项

当渲染列表项时,通常更有效的方法是让列表组件只选择 ID,并让单个项组件选择它们自己的数据

这种方法可以通过最小化当单个项更改时整个列表的重新渲染来提高性能。

来源: docs/tutorials/fundamentals/part-5-ui-and-react.md422-460

故障排除

常见问题

  1. 状态更改时组件未重新渲染:

    • 检查你的 selector 是否每次都返回新的对象/数组引用
    • 考虑使用 shallowEqual 作为相等函数
    • 确保你在 reducer 中正确地不可变地更新状态
  2. TypeScript dispatch 错误:

    • 默认的 useDispatch 不了解 thunk 或中间件
    • 请改用预类型化的 useAppDispatch hook
  3. 重新渲染过多:

    • 检查你的 selector 是否每次都返回新的引用
    • 考虑使用 Redux Toolkit 或 Reselect 中的 createSelector 来 memoize selector

来源: docs/faq/ReactRedux.md51-84 docs/faq/ReactRedux.md85-125

从 connect 迁移

如果你正在从旧的 connect API 迁移到 hooks,请遵循以下模式:

来源: docs/usage/migrating-to-modern-redux.mdx36-261

结论

React-Redux hooks 提供了一个更简单、更直观的 API,用于将 React 组件连接到 Redux store。通过使用 useSelectoruseDispatch,你可以访问 Redux 状态并 dispatch actions,而无需 connect 高阶组件模式的开销。当与 TypeScript 结合使用时,创建这些 hooks 的预类型化版本可在整个应用程序中提供出色的类型安全。

有关复杂的 Redux 使用模式,包括 memoized selector、规范化状态和其他高级概念,请参阅 Advanced React-Redux Patterns