【问题标题】:Bloc listener not invoked without a delay没有延迟调用 Bloc 侦听器
【发布时间】:2020-10-24 17:30:19
【问题描述】:

我已经定义了以下肘。

@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),
    ));
  }
}

但是,即使在调用 emit 之后,监听这个 bloc 的 BlocListener 也没有被调用。但是当我在发出调用之前添加零延迟时,一切都按预期工作。

Future<void> authCheck() async {
  await Future.delayed(Duration.zero);
  emit(_authService.signedInUser.fold(
    () => AuthState.unauthenticated(none()),
    (user) => AuthState.authenticated(user),
  ));
}

我尝试了这种延迟,因为对于其他导致一些后端调用(有一些延迟)的事件,emit 工作得很好。但我很确定这不是它应该如何工作的。我在这里遗漏了什么吗?

编辑: 添加使用 BlocListener 的 SplashPage 小部件代码。

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(
        ....
      ),
    );
  }
}

AuthState 是 freezed union

@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)时,一切都按预期工作。

【问题讨论】:

  • 能否添加调用 authCheck 和创建 bloc 的代码
  • @PietervanLoon 添加了使用 BlocListener 的小部件代码。
  • 这不是我问的 XD。但我现在意识到,这些状态可能被视为同一个状态,所以你能分享AuthState 代码
  • 哦,我误读了您之前的评论。编辑了更多信息。此外,正如最后所写,当我将此 Cubit 转换为具有完全相同功能的 Bloc 时,一切正常。

标签: flutter bloc flutter-bloc


【解决方案1】:

没有延迟,直接从提供者的 create 方法调用发射。这意味着侦听器尚未(完全)构建,因此当您发出状态时没有要调用的侦听器。

因此,通过添加延迟,您可以让侦听器首先订阅流,从而在您发出新状态时调用它。

【讨论】:

    【解决方案2】:

    对我来说,延迟并不完美。所以我找到了这个解决方案,也许可以帮助某人:

      @override
      void initState() {
        super.initState();
        WidgetsBinding.instance?.addPostFrameCallback((_) async {
          await myCubit.doSomethingFun();
        });
      }
    

    @Pieter 是对的,只有在构建小部件时才会调用监听器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 2020-03-27
      • 2012-09-22
      • 2021-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多