Flutter Bloc的mapEventToState仅执行一次后续UI无更新问题求解
问题核心原因
Bloc默认会对比前后两次yield的状态,如果是同一个对象实例,就会判定状态无变化,不会触发UI的builder回调。你代码的问题出在两处:
- AuthState是可变类,没有实现相等性对比逻辑
- 你在mapEventToState中直接修改原state对象的属性,yield的还是旧的状态实例,Bloc识别不到状态变更
修复步骤
1. 改造AuthState为不可变类,支持相等性判断
推荐用Equatable简化代码,首先在pubspec.yaml的dependencies下添加依赖:
equatable: ^2.0.5
然后修改auth_state.dart:
import 'package:equatable/equatable.dart'; class AuthState extends Equatable { final bool isLoggedIn; const AuthState({this.isLoggedIn = false}); @override List<Object?> get props => [isLoggedIn]; }
如果不想引入Equatable,也可以自己重写==和hashCode:
class AuthState { final bool isLoggedIn; AuthState({this.isLoggedIn = false}); @override bool operator ==(Object other) => identical(this, other) || other is AuthState && runtimeType == other.runtimeType && isLoggedIn == other.isLoggedIn; @override int get hashCode => isLoggedIn.hashCode; }
2. 修改AuthBloc逻辑,每次yield新的状态实例
不要修改原state对象,每次都创建新的AuthState实例返回:
class AuthBloc extends Bloc<AuthEvent, AuthState> { AuthBloc() : super(const AuthState()); @override Stream<AuthState> mapEventToState(AuthEvent event) async* { switch (event.eventType) { case EventType.login: yield AuthState(isLoggedIn: true); break; case EventType.logout: yield AuthState(isLoggedIn: false); break; default: throw Exception('Event not found $event'); } } }
其余页面代码无需修改,调整后Bloc就能正确识别状态变更,触发UI刷新。
内容的提问来源于stack exchange,提问作者Lyle Phillips
相关产品推荐
相关产品推荐

