3.2 原生方案
Flutter 提供了三种原生无需第三方依赖的状态管理方案分别适用于不同规模和场景。一、setState局部状态管理setState是 Flutter 最基础的状态管理方式适合管理单个 Widget 内的局部状态。1.1 基本用法classShoppingCartButtonextendsStatefulWidget{constShoppingCartButton({super.key});overrideStateShoppingCartButtoncreateState()_ShoppingCartButtonState();}class_ShoppingCartButtonStateextendsStateShoppingCartButton{int _itemCount0;bool _isAddingfalse;Futurevoid_addToCart()async{setState(()_isAddingtrue);try{awaitCartService.addItem();setState(()_itemCount);}finally{setState(()_isAddingfalse);}}overrideWidgetbuild(BuildContextcontext){returnBadge(label:Text($_itemCount),isLabelVisible:_itemCount0,child:IconButton(icon:_isAdding?constSizedBox(width:20,height:20,child:CircularProgressIndicator(strokeWidth:2),):constIcon(Icons.shopping_cart),onPressed:_isAdding?null:_addToCart,),);}}1.2 ValueNotifier ValueListenableBuilder比 setState 更加精细避免整个 Widget 重建classCounterPageextendsStatelessWidget{final_counterValueNotifierint(0);CounterPage({super.key});overrideWidgetbuild(BuildContextcontext){returnScaffold(body:Center(// 只有 ValueListenableBuilder 内部重建不影响整个页面child:ValueListenableBuilderint(valueListenable:_counter,builder:(context,value,child){returnText(Count:$value,style:constTextStyle(fontSize:24));},),),floatingActionButton:FloatingActionButton(onPressed:()_counter.value,child:constIcon(Icons.add),),);}}1.3 setState 的正确姿势// ✅ 只在 setState 中修改状态setState((){_isLoadingtrue;_errorMessagenull;});// ❌ 错误在 setState 外修改可能导致 UI 不更新_isLoadingtrue;// 没有通知 Flutter 重建setState((){});// 空 setState不推荐// ✅ 避免在 setState 中做耗时操作setState((){// 只做赋值不做网络请求或复杂计算_datanewData;});二、InheritedWidget 进阶跨组件共享数据InheritedWidget是 Flutter 状态共享的底层机制Provider 等第三方框架都基于它实现。2.1 基本实现// 1. 定义 InheritedWidgetclassThemeInheritedextendsInheritedWidget{finalThemeDatathemeData;finalVoidCallbacktoggleTheme;constThemeInherited({super.key,requiredthis.themeData,requiredthis.toggleTheme,requiredsuper.child,});// 提供 of 方法方便子 Widget 获取staticThemeInheritedof(BuildContextcontext){finalresultcontext.dependOnInheritedWidgetOfExactTypeThemeInherited();assert(result!null,No ThemeInherited found in context);returnresult!;}// 决定何时通知依赖的子 Widget 更新overrideboolupdateShouldNotify(ThemeInheritedoldWidget){returnthemeData!oldWidget.themeData;}}// 2. 在祖先 Widget 中提供classAppRootextendsStatefulWidget{overrideStateAppRootcreateState()_AppRootState();}class_AppRootStateextendsStateAppRoot{ThemeData_themeThemeData.light();void_toggleTheme(){setState((){_theme_theme.brightnessBrightness.light?ThemeData.dark():ThemeData.light();});}overrideWidgetbuild(BuildContextcontext){returnThemeInherited(themeData:_theme,toggleTheme:_toggleTheme,child:MaterialApp(theme:_theme,home:constHomePage()),);}}// 3. 在任意子 Widget 中消费classThemeToggleButtonextendsStatelessWidget{overrideWidgetbuild(BuildContextcontext){finalinheritedThemeInherited.of(context);returnSwitch(value:inherited.themeData.brightnessBrightness.dark,onChanged:(_)inherited.toggleTheme(),);}}2.2 maybeOf vs of// of找不到时直接 assert 报错推荐必须依赖时使用staticMyDataof(BuildContextcontext)context.dependOnInheritedWidgetOfExactTypeMyData()!;// maybeOf找不到时返回 null可选依赖时使用staticMyData?maybeOf(BuildContextcontext)context.dependOnInheritedWidgetOfExactTypeMyData();三、Provider 体系Provider 是 Flutter 官方推荐的状态管理方案基于 InheritedWidget提供更简洁的 API。3.1 安装dependencies:provider:^6.1.03.2 ChangeNotifier Provider第一步定义 ChangeNotifier 模型classCartModelextendsChangeNotifier{finalListCartItem_items[];ListCartItemgetitemsList.unmodifiable(_items);// 只读访问intgetitemCount_items.length;doublegettotalPrice_items.fold(0,(sum,item)sumitem.price*item.quantity);voidaddItem(Productproduct){finalindex_items.indexWhere((item)item.productIdproduct.id);if(index0){_items[index]_items[index].copyWith(quantity:_items[index].quantity1,);}else{_items.add(CartItem.fromProduct(product));}notifyListeners();// 通知所有监听者重建}voidremoveItem(StringproductId){_items.removeWhere((item)item.productIdproductId);notifyListeners();}voidclear(){_items.clear();notifyListeners();}}第二步在 Widget 树中注入// 单个 ProviderChangeNotifierProviderCartModel(create:(_)CartModel(),child:constMyApp(),)// 多个 ProviderMultiProvider(providers:[ChangeNotifierProvider(create:(_)CartModel()),ChangeNotifierProvider(create:(_)UserModel()),ChangeNotifierProvider(create:(_)ThemeModel()),// Provider.value共享已有实例ProviderApiService.value(value:ApiService.instance),],child:constMyApp(),)第三步在子 Widget 中消费// 方式一Provider.of会触发整个 Widget 重建Widgetbuild(BuildContextcontext){finalcartProvider.ofCartModel(context);returnText(共${cart.itemCount}件商品);}// 方式二context.watch效果同上语法更简洁Widgetbuild(BuildContextcontext){finalcartcontext.watchCartModel();returnText(共${cart.itemCount}件商品);}// 方式三context.read仅读取不监听不触发重建ElevatedButton(onPressed:()context.readCartModel().addItem(product),child:constText(加入购物车),)// 方式四context.select精确监听特定字段Widgetbuild(BuildContextcontext){// 只有 itemCount 变化才重建totalPrice 变化不触发finalcountcontext.selectCartModel,int((cart)cart.itemCount);returnText(共$count件);}3.3 Consumer提供更细粒度的重建控制Scaffold(appBar:AppBar(title:constText(购物车),actions:[// Consumer只有 CartModel 变化时这里才重建ConsumerCartModel(builder:(context,cart,child){returnBadge(label:Text(${cart.itemCount}),child:child!,);},child:constIcon(Icons.shopping_cart),// 静态子 Widget不随状态重建),],),body:ConsumerCartModel(builder:(context,cart,_){if(cart.items.isEmpty){returnconstEmptyCartWidget();}returnCartItemList(items:cart.items);},),)3.4 Selector比 Consumer 更精细只监听状态的部分字段// 只有 totalPrice 变化才重建此组件SelectorCartModel,double(selector:(_,cart)cart.totalPrice,builder:(context,totalPrice,_){returnText(总计¥${totalPrice.toStringAsFixed(2)},style:Theme.of(context).textTheme.titleLarge,);},)// 监听多个字段SelectorCartModel,(int,double)(selector:(_,cart)(cart.itemCount,cart.totalPrice),builder:(context,(count,price),_){returnText($count件¥${price.toStringAsFixed(2)});},)3.5 ProxyProvider派生状态MultiProvider(providers:[ProviderApiService(create:(_)ApiService()),// ProductRepository 依赖 ApiServiceProxyProviderApiService,ProductRepository(update:(_,apiService,__)ProductRepository(apiService),),// 监听用户状态变化派生出相关数据ChangeNotifierProxyProviderUserModel,CartModel(create:(_)CartModel(),update:(_,user,cart)cart!..updateUser(user),),],child:constMyApp(),)小结方案适用场景重建粒度复杂度setState单 Widget 内的局部状态整个 Widget最低ValueNotifier局部需要精细控制仅 ValueListenableBuilder低InheritedWidget框架级数据共享依赖的子 Widget中Provider.of全局状态消费整个 Widget中Consumer局部重建Consumer 内部中Selector精确字段监听仅选择字段变化时中 下一节3.3 第三方框架GetX / Riverpod / Bloc