Flutter问题:BlocConsumer未监听Bloc传递的状态
问题根源与修复方案
核心问题:Bloc实例不统一
你在SignInScreen中手动创建了一个新的AuthBloc实例:
final _authBloc = AuthBloc();
而AuthScreen中的BlocConsumer监听的是MultiBlocProvider提供的全局AuthBloc实例。两个不同的Bloc实例完全独立,你给局部Bloc添加事件,全局Bloc的状态自然不会变化,导致BlocConsumer始终停留在初始状态。
修复步骤
1. 修改SignInScreen,使用全局Bloc实例
删除_SignInScreenState中的final _authBloc = AuthBloc();,在_submit方法中通过context.read获取全局Bloc:
void _submit(BuildContext context) { FocusScope.of(context).unfocus(); if(!_formKey.currentState!.validate()) { return; } _formKey.currentState!.save(); UserSignIn user = UserSignIn(login: _email!, password: _pass!); // 替换成全局Bloc实例 context.read<AuthBloc>().add(AuthSignInEvent(user: user)); }
2. 修复AuthScreen中的状态判断错误
在AuthScreen的listener中,错误地将AuthSignUpEvent(事件类)当成状态判断,应该改为AuthSignUpState:
listener: (context, state) { print(state); // 修正状态判断 if (state is AuthSignInState || state is AuthSignUpState) { Navigator.of(context).popAndPushNamed(HomePage.id); } },
3. 完善AuthBloc的注册逻辑
当前AuthSignUpEvent处理完成后没有emitAuthSignUpState,导致注册成功后不会触发页面跳转,需要补充:
on<AuthSignUpEvent>((event, emit) async { emit(AuthLoadingState()); try { final user = event.user; final UserCredential userCredential = await auth.createUserWithEmailAndPassword( email: event.user.login, password: event.user.password); await FirebaseFirestore.instance .collection('users') .doc(userCredential.user!.uid) .set({ 'userId': userCredential.user!.uid, 'mail' : user.login, 'username' : user.username, }); // 补充emit注册成功状态 emit(AuthSignUpState()); } on FirebaseAuthException catch (e) { // ... 原有错误处理代码 } catch (error) { // ... 原有错误处理代码 } });
额外注意事项
- 确保所有需要使用
AuthBloc的地方,都通过context.read<AuthBloc>()或context.watch<AuthBloc>()获取全局实例,避免手动创建新实例。 - 可以在
SignInScreen的build方法中使用BlocListener监听局部状态变化(比如错误提示),不过当前AuthScreen的BlocConsumer已经处理了全局状态的UI反馈。
内容的提问来源于stack exchange,提问作者Maxim
相关产品推荐
相关产品推荐

