Flutter Bloc返回上页后无法再次触发SubmitDataEvent问题求助
问题根因
- 你使用的是依赖注入全局实例化的
SubmitPersonalDetailsBloc,即便第一个页面销毁调用了bloc.close(),全局注入容器里保存的还是已经被关闭的Bloc实例,第二次进入页面拿到的还是这个已关闭实例,自然无法接收新的SubmitDataEvent()事件 - 跳转时用的
Navigator.popAndPushNamed()逻辑不符合你的场景:该方法会先销毁当前第一个页面,再push第二个页面,你返回的时候其实是重新创建了第一个页面,但拿到的还是旧的已关闭Bloc实例 - 在
dispose生命周期中调用bloc.emit()是无效操作,此时Bloc已经进入销毁流程,状态更新不会生效,也没有业务意义
解决方案
方案1(更推荐,页面Bloc互相隔离)
不要在页面的initState里取全局注入的Bloc单例,改为在BlocProvider的create方法中直接创建新的Bloc实例,保证每次页面初始化都会生成全新的、可用的Bloc:
// 删掉initState里的 bloc = injection<SubmitPersonalDetailsBloc>(); 这行代码 @override Widget buildView(BuildContext context) { return Scaffold( body: BlocProvider<SubmitPersonalDetailsBloc>( // 这里直接创建新实例,不用全局注入的单例 create: (_) => SubmitPersonalDetailsBloc(), child: BlocListener<SubmitPersonalDetailsBloc, BaseState<PersonalDetailsState>>( // 原有listener逻辑保持不变 listener: (context, state) { if (state is LoadingSubmitPersonalDetailsState) { EasyLoading.show(status: 'Submitting Data'); } if (state is SubmitPersonalDetailsSuccessState) { setState(() { submitPersonalDetailsResponseEntity = state.submitPersonalDetailsResponseEntity; }); if (submitPersonalDetailsResponseEntity!.responseCode == "00") { EasyLoading.showSuccess('Done!'); EasyLoading.dismiss(); // 跳转方法修改,不用popAndPushNamed,用普通push保留第一个页面在路由栈中,返回时无需重建页面 Navigator.pushNamed(context, '你的第二个页面路由名'); } } else if (state is SubmitPersonalDetailsFailedState) { EasyLoading.showError(state.error); } }, // 原有子组件逻辑保持不变 ), ), ); }
BlocProvider会自动管理Bloc的生命周期,页面销毁时会自动关闭对应Bloc实例,你不需要在dispose中手动写Bloc关闭逻辑。
方案2(必须使用全局Bloc单例时适用)
如果业务要求必须复用全局注入的Bloc单例:
- 删掉
dispose方法中bloc.close()的逻辑,不要关闭全局Bloc实例 - 在Bloc中新增
ResetStateEvent事件,收到该事件时直接emitInitialState完成状态重置 - 在跳转到第二个页面之前,给Bloc添加这个重置事件,保证返回第一个页面时Bloc状态已经回到初始值
内容的提问来源于stack exchange,提问作者Akila Ishan
相关产品推荐
相关产品推荐

