3.1 状态管理概述

张开发
2026/4/13 6:02:12 15 分钟阅读

分享文章

3.1 状态管理概述
状态管理是 Flutter 应用开发中最核心的话题之一。选择合适的状态管理方案直接影响项目的可维护性和开发效率。一、什么是状态State在 Flutter 中状态是指会随时间变化、并影响 UI 展示的数据。// 这些都是状态int _counter0;// 计数器bool _isLoadingfalse;// 加载状态User?_currentUser;// 当前用户ListProduct_cart[];// 购物车列表ThemeMode_themeThemeMode.system;// 主题模式二、局部状态 vs 全局状态2.1 局部状态Local State只在单个 Widget 或小范围内使用的状态生命周期与 Widget 相同。特征仅当前 Widget 及其子 Widget 需要访问不需要跨页面或跨组件共享组件销毁时状态随之消失适合的状态类型示例说明输入框内容只有当前表单关心展开/折叠状态当前卡片的展开状态页面切换索引当前 Tab 页下标加载/提交状态当前按钮的 loading 状态动画控制器状态只影响当前动画实现方案setState/ValueNotifierclassExpandableCardextendsStatefulWidget{constExpandableCard({super.key});overrideStateExpandableCardcreateState()_ExpandableCardState();}class_ExpandableCardStateextendsStateExpandableCard{bool _expandedfalse;// 局部状态仅此卡片关心overrideWidgetbuild(BuildContextcontext){returnCard(child:Column(children:[ListTile(title:constText(点击展开),trailing:Icon(_expanded?Icons.expand_less:Icons.expand_more),onTap:()setState(()_expanded!_expanded),),if(_expanded)constPadding(padding:EdgeInsets.all(16),child:Text(详细内容...),),],),);}}2.2 全局状态Global State需要在多个 Widget、多个页面之间共享的状态。特征多个不相关的 Widget 都需要读取状态变化需要通知所有依赖方更新 UI生命周期独立于特定 Widget适合的状态类型示例说明用户登录信息所有页面都需要判断登录状态购物车数据底部 Tab、购物车页面都需要应用主题全局生效多语言设置全局生效消息未读数多处展示角标网络连接状态全局监听实现方案Provider / Riverpod / GetX / Bloc三、如何选择状态管理方案你的状态需要跨 Widget 共享吗 ├── 否 → setState / ValueNotifier局部状态 └── 是 → 是否只是 2-3 层祖先-子孙关系 ├── 是 → InheritedWidget / Provider轻量 └── 否 → 复杂业务逻辑 ├── 小/中型项目 → Provider / GetX / Riverpod └── 大型项目事件驱动 → Bloc / Redux方案对比矩阵方案学习曲线适用规模响应式依赖注入推荐场景setState⭐小❌❌局部简单状态InheritedWidget⭐⭐小-中✅❌框架级数据传递Provider⭐⭐中✅✅中型项目GetX⭐⭐中✅✅快速开发Riverpod⭐⭐⭐中-大✅✅现代推荐方案Bloc⭐⭐⭐⭐大✅✅企业级事件驱动四、状态管理的核心问题4.1 状态提升Lifting State Up当两个兄弟 Widget 需要共享状态时将状态提升到共同的父 Widget 中// ❌ 不好两个兄弟 Widget 各自持有状态无法同步classSiblingAextendsStatefulWidget{...}// 持有 selectedColorclassSiblingBextendsStatefulWidget{...}// 需要 selectedColor 但获取不到// ✅ 好状态提升到父 WidgetclassParentWidgetextendsStatefulWidget{overrideStateParentWidgetcreateState()_ParentWidgetState();}class_ParentWidgetStateextendsStateParentWidget{Color_selectedColorColors.blue;// 提升到父级overrideWidgetbuild(BuildContextcontext){returnColumn(children:[ColorPicker(selectedColor:_selectedColor,onColorChanged:(color)setState(()_selectedColorcolor),),ColorPreview(color:_selectedColor),// 消费状态],);}}4.2 单向数据流好的状态管理遵循单向数据流原则用户操作 (Action) ↓ 状态更新 (State Update) ↓ UI 重建 (Rebuild) ↓ 用户操作 (Action) ← 循环4.3 状态的不可变性推荐使用不可变状态对象每次更新返回新对象immutableclassCartState{finalListCartItemitems;finaldouble totalPrice;finalbool isLoading;constCartState({this.itemsconst[],this.totalPrice0,this.isLoadingfalse,});// copyWith 模式创建新状态CartStatecopyWith({ListCartItem?items,double?totalPrice,bool?isLoading,}){returnCartState(items:items??this.items,totalPrice:totalPrice??this.totalPrice,isLoading:isLoading??this.isLoading,);}}小结概念要点局部状态不需要共享用 setState 即可全局状态需要跨组件共享选择合适框架状态提升共同父 Widget 持有状态向下传递单向数据流Action → State → UI 循环不可变状态copyWith 模式便于追踪变化 下一节3.2 原生方案setState / InheritedWidget / Provider

更多文章