状态管理真正让人头疼的不是工具,而是边界模糊。只要边界清晰,无论 Provider、Riverpod 还是 BLoC,都能发挥作用。本文给出一套边界设计方法,帮助你把复杂度关进可维护的盒子。
1. 先定义三类状态
把状态按“作用域”分成三类:
- 页面状态:只影响单页,如表单输入、局部 loading
- 模块状态:影响某个业务模块,如商品列表/聊天会话
- 全局状态:跨模块共享,如登录态、主题、语言
只要先分清这三类,后续选型就不会乱。
2. 状态归属的三问法
遇到一个状态,先问:
- 谁负责更新它?
- 哪些页面/模块需要读取它?
- 生命周期是否跨页面?
如果答案清晰,状态自然有归属;如果答案模糊,就说明设计本身有问题。
3. 划清责任:状态负责“业务”,UI 负责“展示”
常见的问题是 UI 组件里夹杂大量业务逻辑,导致:
- 组件难复用
- 逻辑难测试
- 状态依赖混乱
解决方案:
- UI 只订阅状态并渲染
- 业务逻辑集中在状态层
- 状态层提供明确的“动作接口”
这样 UI 层会更轻,业务逻辑更集中。
4. 分层状态:避免“全局污染”
过度全局化是灾难,实践建议:
- 页面状态用
StatefulWidget或局部 Provider - 模块状态在模块入口注入
- 全局状态仅保留不可避免的跨模块数据
目标是:全局状态最小化。
5. 数据流:单向流动是默认解
无论工具是什么,单向数据流都能显著降低复杂度:
- 事件 → 状态更新 → UI 渲染
- 避免 UI 直接写入复杂状态
- 通过统一入口修改状态
这能让状态变化可追踪、可调试。
6. 常见反模式
- 把网络请求直接写在 Widget 里
- 同一个状态被多个模块同时修改
- 全局状态滥用导致难以追踪
这些问题出现时,通常不是“框架选择问题”,而是边界问题。
7. 一份边界设计清单
- 明确状态作用域(页面 / 模块 / 全局)
- 定义状态归属(谁更新、谁使用)
- UI 不承载业务逻辑
- 全局状态最小化
- 数据流单向
总结
Flutter 状态管理的重点是边界设计。只要边界清晰,工具只是实现方式。把复杂度关进边界里,团队协作和长期维护会轻很多。