Flutter BLoC:修改单个变量时如何持久化状态?
解决单个状态变量修改时其他变量重置的问题
你的问题出在创建新状态时只传入了要修改的变量,其他变量都使用了父类的默认值,导致每次更新都会把未指定的变量重置回初始状态。下面是两种可行的解决办法:
方法一:给AuthSignInState添加copyWith方法(推荐)
这是Flutter状态管理中最常用的方式,通过基于当前状态复制出仅修改指定字段的新状态,自动保留其他变量的当前值。
修改你的AuthSignInState代码:
class AuthSignInState { final String errorMessage; final bool errorSignIn; final String signUpType; final bool isLoading; final String currentUser; final Sync? user; const AuthSignInState({ this.signUpType = 'email', this.errorMessage = '', this.errorSignIn = false, this.isLoading = false, this.currentUser = '', this.user, }); // 添加copyWith方法 AuthSignInState copyWith({ String? errorMessage, bool? errorSignIn, String? signUpType, bool? isLoading, String? currentUser, Sync? user, }) { return AuthSignInState( errorMessage: errorMessage ?? this.errorMessage, errorSignIn: errorSignIn ?? this.errorSignIn, signUpType: signUpType ?? this.signUpType, isLoading: isLoading ?? this.isLoading, currentUser: currentUser ?? this.currentUser, user: user ?? this.user, ); } @override List<Object?> get props => [errorMessage, errorSignIn, signUpType, isLoading, currentUser, user]; }
然后在你的Bloc reducer中,处理更新signUpType的逻辑时,用当前状态调用copyWith:
// 假设你的事件是SetSignInTypeEvent,携带type参数 AuthSignInState _handleSetSignInType(AuthSignInState state, SetSignInTypeEvent event) { return state.copyWith(signUpType: event.type); }
这样修改后,只有signUpType会被更新,其他变量都会保留当前状态的值。
方法二:修改状态子类的构造逻辑(不推荐,代码冗余)
如果你坚持用子类的方式来定义状态更新,需要在子类构造时传入当前状态的所有变量,而不是只传要修改的字段:
class SetSignInTypeState extends AuthSignInState { SetSignInTypeState(AuthSignInState currentState, String type) : super( signUpType: type, errorMessage: currentState.errorMessage, errorSignIn: currentState.errorSignIn, isLoading: currentState.isLoading, currentUser: currentState.currentUser, user: currentState.user, ); @override List<Object?> get props => [signUpType, errorMessage, errorSignIn, isLoading, currentUser, user]; }
然后在reducer中创建这个子类时,传入当前状态:
AuthSignInState _handleSetSignInType(AuthSignInState state, SetSignInTypeEvent event) { return SetSignInTypeState(state, event.type); }
这种方式需要手动传递所有变量,代码冗余,后续新增字段时还要修改子类构造,不如copyWith灵活。
内容的提问来源于stack exchange,提问作者Cris
相关产品推荐
相关产品推荐

