React 状态归属:不要把所有状态都塞进全局 Store

📅 2026/7/5 2:08:33
React 状态归属:不要把所有状态都塞进全局 Store
React 状态归属不要把所有状态都塞进全局 Store一、全局 Store 不是垃圾桶React 项目里状态一复杂很多团队会下意识塞进全局 Store。短期看方便任何组件都能读写长期看依赖关系会变得模糊组件重渲染也更难控制。状态归属的关键是判断它属于谁、生命周期多长、是否跨页面共享、是否需要持久化。不是所有状态都值得全局化。很多局部交互状态留在组件内反而更清楚。二、状态可以按生命周期分层flowchart TD A[组件局部状态] -- B[页面状态] B -- C[跨组件共享状态] C -- D[服务端缓存] D -- E[持久化偏好]输入框展开、弹窗开关、临时 hover适合组件局部状态。筛选条件、分页、Tab适合页面状态。用户信息、权限和主题偏好才更适合全局或持久化。服务端数据不要简单塞进业务 Store。它有加载、错误、过期、重新验证和缓存一致性问题。使用专门的数据请求缓存会比自己维护一堆 loading 和 error 更稳。三、全局状态要有选择器const userName useUserStore((s) s.profile.name)组件订阅全局 Store 时不要直接拿整个对象。选择器可以缩小订阅范围减少无关重渲染。状态管理库支持浅比较时也要合理使用避免每次返回新对象。const filters useMemo(() ({ status, keyword }), [status, keyword])派生状态不要重复存储。能从已有状态计算出来就不要再写一份。重复状态会带来同步问题尤其在异步请求和表单编辑中很容易出错。四、状态边界要能被测试state_rule: local: modal_open page: search_params global: current_user团队可以把状态归属写成规则。Code Review 时先问这个状态是否真的跨页面共享是否需要 URL 化是否需要持久化是否能从服务端缓存获得。问题问清楚全局 Store 会干净很多。性能排查时也要看状态更新路径。一次输入导致整页重渲染通常说明状态放得太高或订阅太宽。React DevTools 和渲染计数能快速暴露问题。URL 状态也要单独考虑。搜索词、筛选条件、分页和排序经常需要分享、刷新恢复和浏览器前进后退这类状态放在 URL 比放在 Store 更合适。URL 是一种天然的状态容器但要控制序列化复杂度不要把大对象塞进查询参数。表单状态则更适合交给表单库或局部容器。未提交的输入、校验错误和 touched 状态通常只属于当前表单。把这些塞进全局 Store会让其他组件看到大量无关变化还会让清理逻辑变复杂。跨页面共享状态要定期审计。某个状态最初需要全局后来业务收缩后可能只剩单页面使用。没有审计Store 会越积越大最后没人敢动。状态更新还要控制批量边界。一次用户操作如果触发多个全局字段连续更新订阅组件可能经历多次无意义渲染。可以通过批处理、事务式 action 或合并派生状态减少抖动。状态管理不是只看读写方便也要看更新传播成本。最后状态归属要写进组件设计文档。组件接收哪些 props内部维护哪些状态哪些变化通过事件抛出哪些数据来自服务端缓存都应该清楚。边界写明白后续接手的人才不会继续往全局 Store 里塞东西。五、总结React 状态归属要按生命周期和共享范围分层。局部状态留在组件页面状态靠路由或页面容器全局 Store 只放真正跨域共享的数据。状态不是放得越集中越好。边界越清楚组件越容易维护性能问题也越容易定位。