如何无需向每个状态传参即可访问Flutter Bloc中的变量?
问题描述
我开发了一个用Bloc做状态管理的Flutter应用,想在Bloc里保存用户列表,方便在应用不同地方访问。但现在每一个状态都得传递用户列表,能不能避免这种重复的样板代码?特别是我不想把用户列表传给FriendAddedState。
现有State代码
@immutable abstract class UsersState { final List<User> users; final User? user; const UsersState({required this.users, required this.user}); } class UsersInitial extends UsersState { UsersInitial() : super(users: [], user: null); } class UsersLoadedState extends UsersState { const UsersLoadedState({required List<User> users, required User? user}) : super(users: users, user: user); } class UsersPendingState extends UsersState { const UsersPendingState({List<User> users = const [], User? user}) : super(users: users, user: user); } class UsersErrorState extends UsersState { final String message; const UsersErrorState( {required List<User> users, required User? user, required this.message}) : super(users: users, user: user); } class FriendAddedState extends UsersState { const FriendAddedState({required List<User> users, required User? user}) : super(users: users, user: user); }
现有Bloc实现代码片段
else if (event is AddFriend) { emit(FriendAddPending(users: users, user: user)); final result = await usecases.addFriend(event.friendId); result.fold((error) { emit(UsersErrorState( users: users, user: user, message: error.message)); }, (success) { user = success; emit(FriendAddedState(users: users, user: user)); }); }
解决方案
核心思路是把共享的状态(用户列表、当前用户)放到Bloc的成员变量中维护,让每个State只承载自身特有的数据,不用重复传递共享数据。
1. 重构State结构
修改抽象基类和具体State,只保留每个状态独有的字段:
@immutable abstract class UsersState {} class UsersInitial extends UsersState {} class UsersLoadedState extends UsersState { final List<User> users; final User? user; const UsersLoadedState({required this.users, required this.user}); } class UsersPendingState extends UsersState {} class UsersErrorState extends UsersState { final String message; const UsersErrorState({required this.message}); } class FriendAddedState extends UsersState {}
2. 调整Bloc内部逻辑
在Bloc类中维护共享的用户状态,emit状态时只传递当前状态需要的特有数据:
class UsersBloc extends Bloc<UsersEvent, UsersState> { final AddFriendUsecase usecases; List<User> _currentUsers = []; User? _currentUser; UsersBloc({required this.usecases}) : super(UsersInitial()) { on<AddFriend>(_onAddFriend); // 其他事件处理... } void _onAddFriend(AddFriend event, Emitter<UsersState> emit) async { emit(UsersPendingState()); final result = await usecases.addFriend(event.friendId); result.fold((error) { emit(UsersErrorState(message: error.message)); }, (success) { _currentUser = success; // 假设添加好友后需要更新用户列表,这里根据实际业务逻辑调整 // _currentUsers = ...; emit(FriendAddedState()); // 如果需要刷新列表展示,可接着emit UsersLoadedState同步最新数据 emit(UsersLoadedState(users: _currentUsers, user: _currentUser)); }); } }
3. UI层访问共享状态
UI层监听Bloc状态时,若需要获取用户列表或当前用户,可直接从Bloc的成员变量获取(也可以在需要展示完整数据时,通过UsersLoadedState传递最新状态,保证数据一致性):
// 在Widget中 BlocBuilder<UsersBloc, UsersState>( builder: (context, state) { final usersBloc = context.read<UsersBloc>(); final currentUsers = usersBloc._currentUsers; final currentUser = usersBloc._currentUser; if (state is FriendAddedState) { // 处理好友添加成功的UI逻辑,同时可使用currentUsers和currentUser return Text("好友添加成功"); } // 其他状态处理... }, )
内容的提问来源于stack exchange,提问作者Ольга Сальникова
相关产品推荐
相关产品推荐

