Flutter升级后BuildContext跨异步间隙警告的解决求助
解决Flutter升级后「Don't use 'BuildContext's across async gaps」警告问题
问题根源
你当前的页面是StatelessWidget,而context.mounted是StatefulWidget的State对象专属属性,StatelessWidget的BuildContext并没有这个getter方法,所以你添加的判断实际上没有生效,警告自然无法消除。
解决方案
方案一:将页面改为StatefulWidget(推荐)
这是最贴合Flutter设计规范的解决方式,mounted属性本来就是为Stateful组件设计的,用来判断组件是否还挂载在组件树中:
修改后的完整代码:
import 'package:bank_sha/shared/theme.dart'; import 'package:bank_sha/ui/widgets/buttons.dart'; import 'package:bank_sha/ui/widgets/profile_menu_item.dart'; import 'package:flutter/material.dart'; // 改为StatefulWidget class ProfilePage extends StatefulWidget { const ProfilePage({super.key}); @override State<ProfilePage> createState() => _ProfilePageState(); } class _ProfilePageState extends State<ProfilePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('My Profile'), ), body: ListView( padding: const EdgeInsets.symmetric( horizontal: 24, ), children: [ const SizedBox( height: 20, ), Container( padding: const EdgeInsets.symmetric( horizontal: 30, vertical: 22, ), decoration: BoxDecoration( color: whiteColor, borderRadius: BorderRadius.circular(20), ), child: Column( children: [ Container( height: 120, width: 120, decoration: const BoxDecoration( shape: BoxShape.circle, image: DecorationImage( image: AssetImage('assets/img_profile.png'), ), ), child: Align( alignment: Alignment.topRight, child: Container( width: 28, height: 28, decoration: BoxDecoration( shape: BoxShape.circle, color: whiteColor, ), child: Center( child: Icon( Icons.check_circle, color: greenColor, size: 24, ), ), ), ), ), const SizedBox( height: 16, ), Text( 'Mr Geblekx', style: blackTextStyle.copyWith( fontSize: 18, fontWeight: medium, ), ), const SizedBox( height: 40, ), ProfileMenuItem( iconUrl: 'assets/ic_edit_profile.png', title: 'Edit Profile', onTap: () async { final result = await Navigator.pushNamed(context, '/pin'); // 直接使用State类的mounted属性判断 if (result == true && mounted) { Navigator.pushNamed(context, '/profile-edit'); } }, ), ProfileMenuItem( iconUrl: 'assets/ic_pin.png', title: 'My Pin', onTap: () async { final result = await Navigator.pushNamed(context, '/pin'); if (result == true && mounted) { Navigator.pushNamed(context, '/profile-edit-pin'); } }, ), ProfileMenuItem( iconUrl: 'assets/ic_wallet.png', title: 'Wallet Settings', onTap: () {}, ), ProfileMenuItem( iconUrl: 'assets/ic_reward.png', title: 'My Rewards', onTap: () {}, ), ProfileMenuItem( iconUrl: 'assets/ic_help.png', title: 'Help Center', onTap: () {}, ), ProfileMenuItem( iconUrl: 'assets/ic_logout.png', title: 'Log Out', onTap: () {}, ), ], ), ), const SizedBox( height: 87, ), CustomTextButton( title: 'Report a Problem', onPressed: () {}, ), const SizedBox( height: 50, ), ], ), ); } }
方案二:不转Stateful,用路由状态判断
如果不想修改组件类型,可以通过ModalRoute判断当前页面是否仍处于导航栈的活跃状态:
修改单个onTap回调示例:
ProfileMenuItem( iconUrl: 'assets/ic_edit_profile.png', title: 'Edit Profile', onTap: () async { final result = await Navigator.pushNamed(context, '/pin'); // 判断当前页面是否为当前活跃路由 if (result == true && ModalRoute.of(context)?.isCurrent == true) { Navigator.pushNamed(context, '/profile-edit'); } }, ),
注:这种方式的可靠性略低于方案一,极端场景下可能存在路由状态判断延迟的问题。
内容的提问来源于stack exchange,提问作者Bayu Febriyono Putra
相关产品推荐
相关产品推荐

