Flutter报navigator._debugLocked错误跳转后返回崩溃如何修复?
问题修复方案
错误原因
- 导航逻辑被错误放在了
BlocConsumer的builder回调中,builder仅用于根据状态返回渲染所需的Widget,禁止处理跳转、弹框这类副作用逻辑。 - 从详情页执行pop返回时,当前页面会触发重绘,此时状态仍然是
UserGetPostByIdSuccessState,会再次触发Navigator.push操作,而此时导航器还在处理pop逻辑处于锁定状态,最终抛出!navigator._debugLocked异常。
修复方法
将导航逻辑移到BlocConsumer专门处理副作用的listener回调中,移除builder中的导航相关代码即可,修改后代码如下:
class UserPosts extends StatelessWidget { @override Widget build(BuildContext context) { return BlocConsumer<UserCubit, UserStates>( // 所有副作用逻辑放在listener中处理 listener: (context, state) { if (state is UserGetPostByIdSuccessState) { Navigator.push( context, MaterialPageRoute(builder: (context) => PostDetails())); } // 可扩展错误状态处理,比如弹提示 if(state is UserGetPostByIdErrorState){ ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("加载帖子失败"))); } }, builder: (context, state) { var cubit = UserCubit.get(context); if (state is UserGetPostByIdLoadingState) { return const CircularProgressIndicator(); } return Scaffold( body: GridView.builder( itemCount: cubit.userPosts.length, gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3), itemBuilder: (context, index) { return Stack( alignment: AlignmentDirectional.bottomEnd, children: [ InkWell( onTap: () async { try { await cubit .getPostById(cubit.userPosts[index].postId!); } catch (error) { print('$error'); } }, child: Container( decoration: BoxDecoration( border: Border.all( color: Colors.grey.withOpacity(0.2))), child: Image( image: NetworkImage( '${cubit.userPosts[index].media.first}')), ), ), cubit.userPosts[index].media.length > 1 ? const Icon( Icons.auto_awesome_motion, ) : const SizedBox() ], ); }), ); }, ); } }
补充优化建议
如果跳转后再次进入该页面不需要保留之前的请求成功状态,可以在UserCubit中跳转后重置状态,或者在导航跳转前加mounted判断避免页面销毁后触发异常。
内容的提问来源于stack exchange,提问作者yyyy
相关产品推荐
相关产品推荐

