React状态管理方案选型
React 中本地状态、Context、Zustand、Redux Toolkit 与 TanStack Query 的常见选型边界。
[!info] related notes
React状态管理方案选型
React 项目里最常见的架构问题之一,不是“有没有状态管理库”,而是没有把本地状态、共享客户端状态和服务器状态分开看。
先分三类状态
本地 UI 状态
例如弹窗开关、输入框内容、局部折叠状态,优先用 useState 或 useReducer。
客户端共享状态
例如登录信息、主题配置、跨页面筛选条件,适合 Context 或专门状态管理库。
服务器状态
例如接口列表、详情数据、缓存和请求状态,更适合 TanStack Query 这类数据获取方案。
为什么很多项目选型会失控
不是因为工具太多,而是因为一开始没把状态类型分开。
最常见的混淆包括:
- 用全局 store 管所有接口缓存
- 用 Context 管所有共享状态
- 用 Redux 解决本该局部解决的问题
- 用本地 state 硬扛跨页面共享流程
一条常见选型线
只在局部使用
用 useState / useReducer。
只是跨层传值
共享客户端状态较多,但希望轻量
可以考虑 zustand。
需要更强约束、可预测状态流和团队规范
可以考虑 Redux Toolkit。
重点是服务端数据缓存、请求状态、失效与重取
优先考虑 TanStack Query,而不是把这类数据全塞进全局 store。
一个更工程化的理解
可以先按“这份状态到底在解决什么问题”来选:
- 控一个弹窗:本地 state
- 跨层传主题:Context
- 客户端共享业务状态:Zustand / Redux Toolkit
- 接口缓存和请求生命周期:TanStack Query
这样比“公司都在用什么”更稳。
面试里怎么回答“全局状态管理怎么选”
这题最稳的答法不是先报库名,而是先分状态类型。
一个更完整的回答可以是:
React 里我会先把状态分成本地 UI 状态、共享客户端状态和服务器状态。局部交互状态优先用
useState或useReducer;只是跨层传值可以用 Context;如果共享客户端状态较多、希望轻量,可以用 Zustand;如果团队需要更强约束和可预测状态流,可以用 Redux Toolkit。至于接口数据、缓存、失效和重取,我更倾向交给 TanStack Query,而不是全塞进全局 store。
面试官真正想听什么
- 你是不是先分状态类型,而不是先选工具
- 你知不知道 Context 不等于完整状态管理方案
- 你是否知道服务端数据和客户端状态最好分开治理
一个很常见的判断框架
本地 UI 状态
- 弹窗开关
- 当前 tab
- 输入框内容
优先局部管理,不要轻易全局化。
共享客户端状态
- 登录态
- 主题
- 跨页面筛选条件
- 某些业务工作台状态
这时再考虑 Context、Zustand 或 Redux Toolkit。
服务器状态
- 列表数据
- 详情数据
- 分页缓存
- 请求 loading / error / stale 状态
这类状态更像“远端数据同步问题”,不只是“本地 store 存一下”。
一个更接近工程的选型结论
- 小而局部:
useState/useReducer - 只是跨层传值:Context
- 轻量共享业务状态:Zustand
- 大团队、强约束、复杂状态流:Redux Toolkit
- 服务端数据缓存和失效:TanStack Query
面试里容易加分的一句
我不会一上来就把接口数据全塞进 Redux 或 Zustand,因为服务器状态和客户端状态的生命周期、更新来源、失效策略并不一样。
常见误区
- 用 Context 扛所有状态问题
- 把接口返回数据长期手工复制到全局 store
- 还没形成复杂共享需求,就提前引入很重的状态体系
最短记忆方式
先分清“本地状态、共享客户端状态、服务器状态”,再谈用哪种工具。