Flutter中MultiBlocProvider在父类,子类BlocListener无法监听状态
解决Flutter中BlocListener无法监听MultiBlocProvider提供的Bloc状态更新问题
问题根源
你在子类页面的BlocListener中手动创建了新的LoginBloc实例,这个实例和MultiBlocProvider在父类中提供的实例完全独立:
- 触发事件时使用的是
BlocProvider.of<LoginBloc>(context)获取的共享实例 - 但
BlocListener监听的是自己new出来的LoginBloc(ApiRepository()),该实例从未收到任何事件,自然监听不到状态更新 - 同时你在
onLogin中调用的_loginBloc.add(...),如果_loginBloc是页面本地实例,会进一步导致事件分散到不同Bloc,加剧状态不同步问题
解决方案
让BlocListener自动从上下文获取MultiBlocProvider提供的共享LoginBloc实例,同时统一使用该实例触发事件:
修改后的子类页面代码
return Scaffold( body: BlocListener<LoginBloc, LoginState>( // 移除bloc参数,BlocListener会自动从context中获取共享的LoginBloc实例 listener: (context, state) { print("state*** $state"); }, child: Container( child: QpSkeletonLoginPage( btnTextStyle: AppTextStyles.btnStyle( context: context, color: ColorConstants.colorWhite), onLogin: () { // 统一使用上下文获取的共享实例触发事件 final loginBloc = BlocProvider.of<LoginBloc>(context); loginBloc.add(GetLoginUpdate("903XXX248","am@ravathi94")); }, btnColor: ColorConstants.colorGreen, )), ), );
补充说明
- BlocProvider的核心作用是在其子Widget树中提供同一个Bloc实例,所有需要使用该Bloc的Widget都应通过
BlocProvider.of<T>(context)、context.read<T>()或context.watch<T>()获取实例,禁止手动创建新实例 - 如果页面内存在
_loginBloc这类本地初始化的变量,建议直接删除,统一使用上下文获取的共享实例,避免多实例共存导致状态不同步
内容的提问来源于stack exchange,提问作者Farhana Naaz Ansari
相关产品推荐
相关产品推荐

