Flutter Bloc登录按钮重复点击致邮箱密码值为空的问题求助
问题根源
你的SignInLoading、SignInSuccess、SignInError状态子类在实例化时,没有继承当前状态中的email和password值,而是使用了SignInState默认的空字符串初始化。例如当你调用emit(SignInError(error: "xxx"))时,新状态的email和password会被重置为空,导致后续读取状态时丢失之前输入的内容。
修改步骤
1. 更新状态子类的构造函数
让所有状态子类在构造时接收并传递父类的email、password、passwordVisible参数,确保状态切换时保留原有输入值:
class SignInState { String email; String password; bool passwordVisible; SignInState({ this.email = "", this.password = "", this.passwordVisible = false, }); List<Object> get props => [email, password, passwordVisible]; SignInState copyWith({ String? email, String? password, bool? passwordVisible, }) { return SignInState( email: email ?? this.email, password: password ?? this.password, passwordVisible: passwordVisible ?? this.passwordVisible, ); } } class SignInLoading extends SignInState { SignInLoading({ super.email, super.password, super.passwordVisible, }); } class SignInSuccess extends SignInState { SignInSuccess({ super.email, super.password, super.passwordVisible, }); } class SignInError extends SignInState { final String error; SignInError({ required this.error, super.email, super.password, super.passwordVisible, }); @override List<Object> get props => [error, email, password, passwordVisible]; }
2. 在Bloc中emit状态时传递当前值
在处理登录事件时,emit错误或成功状态时,将当前state的email、password传递给子类构造:
on<SignInLoginButtonEvent>( (event, emit) async { final email = state.email; final password = state.password; print("Email is $email Password is $password"); if (email.isEmpty) { emit(SignInError( error: "Please Enter Email", email: email, password: password, )); return; // 提前返回,避免后续执行无效逻辑 } else if (password.isEmpty) { emit(SignInError( error: "Please Enter password", email: email, password: password, )); return; } try { final credential = await FirebaseAuth.instance .signInWithEmailAndPassword(email: email, password: password); if (credential.user == null) { emit(SignInError( error: "User Not Found", email: email, password: password, )); return; } if (!credential.user!.emailVerified) { emit(SignInError( error: "Email Not Verified", email: email, password: password, )); return; } if (credential.user != null) { emit(SignInSuccess( email: email, password: password, )); } } on FirebaseAuthException catch (e) { String errorMessage; switch (e.code) { case "user-not-found": errorMessage = "User Not Found"; break; case "wrong-password": errorMessage = "Wrong Password"; break; case "invalid-email": errorMessage = "Invalid Email"; break; default: errorMessage = "Login Failed"; } emit(SignInError( error: errorMessage, email: email, password: password, )); } }, );
额外优化说明
- 在emit错误状态后添加
return,避免后续代码继续执行,减少不必要的逻辑分支。 - 给
SignInError的props添加error字段,确保Bloc能正确识别状态变化。
修改完成后,无论状态如何切换(错误、成功、加载),都会保留用户之前输入的邮箱和密码值,解决点击两次登录按钮后值为空的问题,同时也能修复单独输入邮箱或密码后点击登录,另一个值丢失的问题。
内容的提问来源于stack exchange,提问作者Miraj Hossain Shawon
相关产品推荐
相关产品推荐

