请写一篇关于【Flutter状态管理最佳实践】的技术文章
去年十月的一个周五晚上,北京下着小雨,我瘫在出租屋的沙发上,盯着天花板发呆。房租3500,离公司地铁要45分钟,老婆刚给我发消息说老家县城新开了个产业园,有家做智慧政务App的公司在招Flutter开发,月薪18k起。
那一刻,我脑子里闪过的不是“回不回”,而是:“我这三年从测试转开发,好不容易搞明白的状态管理方案,回去还能用得上吗?”
从点控件到管状态:一个前测试工程师的挣扎
三年前,我还是个整天和Postman、Jenkins打交道的测试工程师。每天的工作就是点点按钮、写写断言、看CI流水线红了没。直到有一天,组长让我试着用Flutter写个内部工具——一个简单的设备巡检记录App。
我照着官方文档抄了个StatefulWidget,点击按钮改个文字,居然跑起来了!当时兴奋得差点把咖啡洒键盘上。可当我加到第三个页面、第五个数据源时,问题来了:状态一多,代码像意大利面,setState() 调用满天飞,改一处崩三处。
那会儿我才意识到,UI是骨架,状态才是灵魂。而我这个“半路出家”的开发者,连灵魂怎么安放都没搞明白。
状态管理选型:一场没有硝烟的战争
刚开始,我啥都不懂,看到社区里有人说“Provider香”,就跟着用。确实,比纯setState清晰多了。但项目越做越大,数据流开始乱套:用户信息、订单列表、网络请求状态……全塞进同一个ChangeNotifier里,代码又回到了“面条时代”。
后来团队接了个新项目,要做一个带实时聊天和运营活动配置的App。产品经理老张(真名张伟)在需求会上拍桌子:“这次必须支持动态换肤、A/B测试、还有灰度发布!运营那边下周就要看效果!”
我坐在角落,心里咯噔一下:这不就是状态管理的终极考场吗?
于是,我和同事小李(比我早转开发半年)花了整整一周时间,对比了市面上主流的方案:
1. Provider + ChangeNotifier
- 优点:轻量、学习成本低、和Flutter原生集成好。
- 缺点:复杂场景下容易变成“上帝对象”,通知粒度粗,刷新效率低。
- 适用:中小型项目,状态逻辑简单。
我们试过,但当运营要求“某个按钮颜色根据后台配置实时变”时,发现每次改配置都要重建整个页面树,性能堪忧。
2. Bloc / Cubit(来自flutter_bloc库)
- 优点:单向数据流清晰,事件驱动,适合复杂业务逻辑;测试友好。
- 缺点:模板代码多,初学者容易懵;对“响应式”思维要求高。
- 适用:中大型项目,强调可维护性和可测试性。
小李力推Bloc,他说:“你不是做过测试吗?Bloc写单元测试简直爽翻!”
我说:“可我现在是开发啊,老板要的是快,不是测得全。”
但后来我发现,越是赶工期,越需要清晰的架构。否则后期改需求,改到想删库跑路。
3. Riverpod
- 优点:解耦彻底,支持异步状态管理,编译时安全,能轻松组合多个状态源。
- 缺点:概念稍新,生态不如Bloc成熟;部分写法反直觉。
- 适用:追求现代化、高性能、未来可扩展的项目。
我是在一次技术分享会上听说Riverpod的。讲者说:“它解决了Provider的依赖注入痛点。” 我当场掏出手机搜文档,越看越觉得——这不就是为我这种“既要又要还要”的人设计的吗?
开发心得:在“快”和“稳”之间找平衡
最终,我们在新项目里采用了 Riverpod + Freezed(用于不可变状态) + AsyncNotifier 的组合。
举个真实场景:运营要上线一个“限时红包雨”活动。规则是:
- 用户进入首页,如果当前时间在活动区间内,显示红包按钮;
- 点击后,调接口领取,成功则弹动画,失败则提示;
- 同一用户只能领一次;
- 活动配置(开始/结束时间、是否开启)由后台动态下发。
用Riverpod,我们可以这样拆解:
// 活动配置状态
final activityConfigProvider = FutureProvider<ActivityConfig>((ref) async {
final api = ref.read(apiProvider);
return api.getActivityConfig();
});
// 用户领取状态(基于配置+用户ID)
final userRedPacketStatusProvider = AsyncNotifierProvider.autoDispose<
UserRedPacketStatus, RedPacketResult>(
() => UserRedPacketStatusNotifier(),
);
class UserRedPacketStatusNotifier extends AutoDisposeAsyncNotifier<RedPacket

评论 0