2020 年的 React 状态管理

2025-05-25

2020 年的 React 状态管理

我时不时会看到一些推文投票,询问我们在 React 中如何进行状态管理。很多情况下,选项仅限于 Redux、MobX 以及最近的 React Context + Hooks。

当然,唯一正确的答案是视情况而定

但这是我针对中型CRUD类单页 React 应用程序所做的事情。

  • 我不使用任何状态管理库。(没有 Redux、没有 MobX、没有 Recoil)。
  • 我尝试使用路由来管理大部分应用状态。这意味着即使应用是单页应用,应用的不同部分也会使用不同的 URL。我使用 React Router 来实现这一点。
  • 我区分了应用程序/UI 状态和远程数据缓存。并使用SWRReact Query来保存远程数据的缓存。
  • 其余的往往是一些 UI 状态的“细节”,比如哪个模态弹窗处于打开状态,或者表单提交前的状态。对于这些,我更喜欢使用useStateuseReducer钩子,将状态保持在靠近使用位置的位置。

URL 中的应用程序状态

应用程序状态必须保存在某个地方。我可以把它隐藏在内存中,也可以把它暴露在 URL 中,这样我们的用户(和开发者)就可以从中受益。

  • 更好的用户体验:用户可以收藏并与他人分享链接和搜索结果
  • 更好的 DX:开发人员不需要在每次刷新浏览器时点击来让应用程序进入某个状态。
  • 更好的文档:帮助页面可以为用户指出他们所描述的应用程序的确切部分。

我尝试将大部分应用程序状态保留在 URL 中,并使用 React Router 来处理路由。

远程数据不是状态:它属于缓存

我再怎么强调也不为过。幸好有人能解释得比我更好:

UI 状态应该与服务器缓存(通常也称为“状态”)分离,当你这样做时,你只需要 React 来进行状态管理。Kent
C. Dodds

这是一篇很棒的文章:为什么您应该将远程数据存储在缓存中(而不是状态中),作者是 Jason Ankers。

“远程数据是只读的。它不属于与我们的 UI 状态相同的位置。”

在类似CRUD的 Web 应用程序中,服务器具有权威性,我不希望客户端的数据副本变得陈旧。

考虑到所有这些,大多数情况下我不需要自定义远程数据的获取和存储方式。我可以将所有这些工作委托给SWRReact Query之类的库。

这些库将获取的数据存储在静态缓存中;并且不需要借助 React Context 与其他组件“共享”数据,因为当缓存发生变化时,所有使用相同数据的组件都会自动重新渲染。

在工作中,我们今年早些时候重构了一个 SPA 应用,使用 SWR,结果显著简化了应用逻辑。此外,我们现在还能享受 SWR 带来的所有优秀功能,例如“焦点重新验证”和“按间隔重新获取”。该应用已运行数月,没有遇到任何问题。

本地 UI 状态应该位于同一位置

上述情况未捕获的几乎所有内容都是本地 UI 状态,例如模态对话框的可见性或表单提交之前的字段。

对于这些情况,我更喜欢将状态保持在靠近使用的位置。我通常会使用useState,偶尔也会使用useReducer

评论?

我很想听听你的想法。

  • 为国家管理做了什么?
  • 您能想到这里未涉及的常见情况吗?

参考:


封面照片由Oshin KhandelwalUnsplash上拍摄

文章来源:https://dev.to/juliang/react-state-management-in-2020-3c58
PREV
8 负载平衡类型
NEXT
SWR 幕后工作原理