#flutter #bloc #flutter-bloc
#flutter #блок #flutter-блок
Вопрос:
Я определил следующий cubit.
@injectable
class AuthCubit extends Cubit<AuthState> {
final IAuthService _authService;
AuthCubit(this._authService) : super(const AuthState.initial());
void authCheck() {
emit(_authService.signedInUser.fold(
() => AuthState.unauthenticated(none()),
(user) => AuthState.authenticated(user),
));
}
}
Но BlocListener, который прослушивает этот блок, не вызывается даже после emit
вызова. Но все работает так, как ожидалось, когда я добавляю нулевую задержку перед вызовом emit.
Future<void> authCheck() async {
await Future.delayed(Duration.zero);
emit(_authService.signedInUser.fold(
() => AuthState.unauthenticated(none()),
(user) => AuthState.authenticated(user),
));
}
Я опробовал эту задержку, потому что для других событий, которые вызывали некоторый внутренний вызов (с некоторой задержкой), emit работал отлично. Но я почти уверен, что это не так, как это должно работать. Я что-то здесь упускаю?
РЕДАКТИРОВАТЬ: добавление кода виджета SplashPage, который использует BlocListener.
class SplashPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocListener<AuthCubit, AuthState>(
listener: (context, state) {
print(state);
},
child: Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
),
);
}
}
Место, где вызывается authCheck(),
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<AuthCubit>(
create: (_) => getIt<AuthCubit>()..authCheck(),
),
],
child: MaterialApp(
....
),
);
}
}
и состояние аутентификации является freezed
объединением
@freezed
abstract class AuthState with _$AuthState {
const factory AuthState.initial() = _Initial;
const factory AuthState.authenticated(User user) = _Authenticated;
const factory AuthState.unauthenticated(Option<AuthFailure> failure) = _Unauthenticated;
const factory AuthState.authInProgress() = _AuthInProgress;
}
Кроме того, когда я реализовал блок (вместо Cubit) с той же функциональностью, все работало так, как ожидалось.
Комментарии:
1. Можете ли вы добавить код, в котором вызывается проверка подлинности и где создается блок
2. @PietervanLoon добавил код виджета, который использует BlocListener.
3. Это не то, о чем я спрашивал XD. Но теперь я понимаю, что, возможно, состояния рассматриваются как одно и то же состояние, поэтому вы можете поделиться
AuthState
кодом4. о, я неправильно истолковал ваш предыдущий комментарий. Отредактировано с добавлением дополнительной информации. Кроме того, как написано в конце, все работало нормально, когда я преобразовал этот Cubit в блок с точно такой же функциональностью.
Ответ №1:
Без задержки emit вызывается непосредственно из метода create поставщика. Это означает, что прослушиватель еще не (полностью) собран, и, следовательно, нет прослушивателя, который должен вызываться при передаче состояния.
Таким образом, добавляя задержку, вы позволяете прослушивателю сначала подписаться на поток, и, таким образом, он вызывается при передаче нового состояния.
Ответ №2:
Для меня задержка работает не идеально. Итак, я нашел это решение, может быть, кому-нибудь поможет:
@override
void initState() {
super.initState();
WidgetsBinding.instance?.addPostFrameCallback((_) async {
await myCubit.doSomethingFun();
});
}
И @Pieter прав, прослушиватель вызывается только при создании виджета.