Flutter 状态管理选型 2026:Riverpod vs Bloc vs setState
Flutter 的状态管理选项比 React 还多——很离谱。每个都有死忠粉。这是一份在生产里真的用每种方案发版过之后的诚实对比。
先分类状态
跟任何 UI 框架一样:
- 临时状态 — 动画控制器、文本编辑、展开折叠。住在
State<>里。 - 应用状态 — 登录、主题、购物车、多页向导。需要工具。
- 服务端状态 —
dio/http+ 缓存层管。
常见错误:用同一种工具对待临时和应用状态。给 bool isExpanded 单独建 Riverpod provider 是过度设计;用 setState 管"当前登录用户"又是耦合不够。
setState 够用的场景
如果你的页面大多自包含,setState + InheritedWidget 真能撑起一个完整 app。只在以下情况伸手要外部库:
- 多个页面要共享同一份可变数据。
- 有非平凡的派生状态。
- 想要不依赖 widget 测试业务逻辑。
Riverpod 3 — 现代默认
Riverpod 是 provider 该长成的样子:不依赖 BuildContext、编译期类型安全、代码生成消除 90% 样板。
class CartNotifier extends _$CartNotifier { List<CartItem> build() => []; void add(CartItem item) => state = [...state, item]; void clear() => state = []; } // 在 widget 里: final cart = ref.watch(cartNotifierProvider);
@riverpod + riverpod_generator 帮你写 Provider 模板代码。Riverpod 3 把 autoDispose 设为默认,异步 provider 组合自然。
选 Riverpod 适合:
- 新应用
- 想让业务逻辑能脱离 widget 测试
- 团队接受代码生成工具链
不适合:团队抵触代码生成工具的话。
Bloc / Cubit — 当显式事件流是目的本身
Bloc 强迫你按"事件 → 状态"思考。这既是优势也是负担。
class CartCubit extends Cubit<List<CartItem>> { CartCubit() : super([]); void add(CartItem item) => emit([...state, item]); }
Cubit 是 "lite 版":扔掉事件类层级。用它替代 Riverpod 也行,只是仪式感更重。
完整 Bloc 闪光时刻:
- 受监管行业(金融、医疗),需要可审计的事件日志。
- 大团队,靠强约定 + lint 降低 review 成本。
- 跨 Bloc 通信(
BlocListener)契合你的心智模型。
不要在小应用上为"未来扩展"用 Bloc。那个未来很少到来。
Signals — 新晋选手
signals_flutter 把 SolidJS 风格的细粒度反应式带到 Flutter。适合:
- 你从 JS 来,怀念 Solid/Vue 的手感。
- 想要外科手术级的重渲染又不想写 selector。
生态相对年轻,能不能用看团队对早期工具的耐受度。
我实际怎么选
- 业余项目:Riverpod 3 + riverpod_generator +
dio+cached_network_image。三行 provider 搞定。 - 20 人团队大型应用:Bloc,因为团队达成共识,约定降低 review 成本。仪式感是 feature 不是 bug。
- 单页原型:setState。真的。
反模式
- 全局 ChangeNotifier 挂在 MaterialApp 上重建整棵树。 用
Consumer+buildWhen做 selector。 - Provider + Bloc + Riverpod 同一项目混用。 选一个,迁移成本远低于维护三个的成本。
- setState 管异步状态。 用 FutureProvider/AsyncNotifierProvider 拿到 loading/error/data 三元组——第一次请求失败你就感谢自己。
一句话总结
- 2026 新项目 → Riverpod 3 + 代码生成。
- 大团队强约定 → Bloc。
- 小自包含 UI → setState。
- 服务端数据 → dio/http + 缓存,不是状态库。
对错答案随团队规模变化,多过随框架版本变化。
相关阅读
React 状态管理 2026:Context、Zustand、Jotai 还是 Redux Toolkit?
2026 年最实用的 React 状态管理选型对比 — Context、Zustand、Jotai、Redux Toolkit 与 React Compiler 时代的新选择。附上选用规则、代码示例与迁移建议。
TypeScript 类型体操:什么时候值,什么时候在炫技
务实的 TypeScript 高级类型指南 — mapped types、conditional types、template literal types 真正能给你什么,什么时候用,什么时候应该退回到朴素代码。
Kubernetes 资源 requests / limits 实战:不会把生产搞挂的设法
怎么在生产里实际设 Kubernetes CPU 与内存的 requests/limits — QoS 类、CPU 节流、OOM kill、那些害公司钱的差别,以及好使的模式。