React 状态管理不适合被理解成“在几个库之间做静态选型”,更适合放进 渐进增强 的视角里看:先用最小成本解决当前问题,再随着状态范围、复杂度和协作成本的上升,逐层增强。

一条渐进增强的主线

React 组件通信方式 useState useReducer useContext zustand / jotai / redux 微前端的渐进式集成

这条线对应的不是“谁替代谁”,而是“问题什么时候升级了”。

第一层:先解决组件通信

在状态管理之前,先看 React 组件通信方式

  • 父传子:props
  • 子传父:回调函数
  • 跨层通信:Context
  • 更大范围协作:状态管理库

如果问题还停留在组件之间的数据传递,通常还没有真正进入“状态管理”阶段。

第二层:局部状态,先用最小解

useState

适合:

  • 单个组件内部的局部状态
  • 结构简单的布尔值、输入框、展开收起、分页页码
  • 业务还没有复杂到需要抽象状态流

判断信号:

  • 状态只在当前组件或很少几个子组件中使用
  • 更新逻辑简单,基本是“设置一个新值”

这是最基础、最符合渐进增强思想的起点。

第三层:逻辑复杂了,但作用域还没变大

useReducer

适合:

  • 状态结构变复杂
  • 更新依赖前一个状态
  • 一个行为会同时影响多个字段

判断信号:

  • useState 开始变成很多个分散的状态片段
  • 更新逻辑逐渐变成条件分支和状态迁移

这里增强的是“状态更新逻辑”,不是“状态共享范围”。

第四层:状态开始跨层共享

useContext

适合:

  • 状态需要跨组件树消费
  • 想避免多层 props drilling
  • 共享的是主题、当前用户、语言、轻量 UI 状态等

判断信号:

  • 中间组件只是在帮忙传值
  • 多个层级都依赖同一份状态

这里增强的是“状态传播方式”。

但要注意:Context 更适合解决共享问题,不天然擅长解决高频更新、复杂调试和大规模拆分问题。

第五层:共享范围和工程复杂度继续上升

Context 已经不够时,就进入外部 store 阶段。这个阶段不是只有一个答案,而是不同方向的增强。

zustand

适合:

  • 想从 Context 平滑升级到独立 store
  • 需要轻量、低心智负担的全局状态管理
  • 更关注开发效率,而不是严格的架构约束

可以理解成对“全局共享状态”的轻量增强。

jotai

适合:

  • 希望按更细粒度拆分状态
  • 不想维护一个很大的中心化 store
  • 状态之间更像依赖图,而不是单棵大树

可以理解成对“状态建模粒度”的增强。

redux

适合:

  • 团队协作规模更大
  • 需要确定性数据流、可追踪性和中间件生态
  • 需要更强的调试能力、规范性和治理能力

可以理解成对“工程治理能力”的增强。

第六层:状态不再只是单应用问题

当应用走向更大的系统边界时,状态管理会继续升级为集成问题。这时可以参考 微前端的渐进式集成

此时要考虑的已经不只是:

  • 状态放在哪个 Hook 或哪个 store

还包括:

  • 哪些状态属于核心应用
  • 哪些状态应该按需同步
  • 哪些状态可以延迟、降级或隔离

这对应了 渐进式集成:从浏览器渲染到框架设计的统一哲学 中的那条主线:先保证核心能力,再做按需增强。

如何判断该不该升级

可以按下面的顺序判断:

  1. 只是组件内部状态?先用 useState
  2. 更新逻辑复杂,但不需要共享?用 useReducer
  3. 需要跨层共享?用 useContext
  4. 共享范围扩大,且更新/拆分/调试变复杂?考虑 zustandjotairedux
  5. 状态跨应用、跨团队、跨边界?进入 微前端的渐进式集成

一个更准确的理解

React 状态管理的核心问题不是“该选哪个库”,而是:

  • 当前状态的作用域有多大
  • 当前状态的更新逻辑有多复杂
  • 当前团队是否需要更强的协作与治理
  • 当前系统是否已经进入跨应用集成阶段

状态管理方案的演进,本质上是一个渐进增强过程:问题没有升级,就不要过度增强;问题一旦升级,就要顺着复杂度自然上移。

相关笔记