【问题标题】:Flutter BlocListener not listening to state changes even this after emitting different statesFlutter BlocListener 即使在发出不同状态后也不会监听状态变化
【发布时间】:2022-10-14 18:23:39
【问题描述】:

我有一个发出一些状态的集团用户状态

这些是我目前的状态

part of 'user_bloc.dart';

@immutable
abstract class UserState extends Equatable {}

class UserInitial extends UserState {
  @override
  List<Object?> get props => [];
}

class UserCreating extends UserState {
  @override
  List<Object?> get props => [];
}

class UserCreated extends UserState {
  late final String message;
  UserCreated(this.message);
  @override
  List<Object?> get props => [];
}

class UserError extends UserState {
  late final String error;
  UserError(this.error);
  @override
  List<Object?> get props => [error];
}

下面也是我的 UserBloc 事件

part of 'user_bloc.dart';

@immutable
abstract class UserEvent extends Equatable {
  @override
  List<Object?> get props => [];
}

class CreateUser extends UserEvent {
  final String name;
  final String email;
  final String password;
  final String? imageUrl;

  CreateUser({
    required this.name,
    required this.email,
    required this.password,
    required this.imageUrl,
  });
}

下面是我发出状态的主要 UserBloc

class UserBloc extends Bloc<UserEvent, UserState> {
  UserRepository userRepository;
  UserBloc(this.userRepository) : super(UserInitial()) {
    on<CreateUser>((event, emit) async {
      emit(UserCreating());
      try {
        final result = await userRepository.signup(
          name: event.name,
          password: event.password,
          email: event.email,
        );
        print(result);
        emit(
          UserCreated('User created successfully'),
        );
      } on DioError catch (error) {
        emit(
          UserError(
            error.response.toString(),
          ),
        );
      } catch (error) {
        emit(
          UserError(
            error.toString(),
          ),
        );
      }
    });
  }
}

我已经用 Multirepository 提供程序和 muiltiblocprovider 包装了我的 MaterialApp,我的所有块都被初始化了。下面是代码。

@override
  Widget build(BuildContext context) {
    return MultiRepositoryProvider(
      providers: [
        RepositoryProvider(create: (context) => UserRepository()),
      ],
      child: MultiBlocProvider(
        providers: [
          BlocProvider<ThemeModeCubit>(
            create: (context) => ThemeModeCubit(),
          ),
          BlocProvider<InternetCubit>(
            create: (context) => InternetCubit(connectivity),
          ),
          BlocProvider(
            create: (context) => UserBloc(
              RepositoryProvider.of<UserRepository>(context),
            ),
          )
        ],
        child: ValueListenableBuilder(...)

最后,我在代码中使用 bloc 监听器来监听 bloc 中的更改,但在更改之前我没有得到任何响应。

final userRepo = RepositoryProvider.of<UserRepository>(context);

child: BlocListener(
            bloc: UserBloc(userRepo),
            listener: (ctx, state) {
              print('listener called');
              if (state is UserCreating) {
                print('loading emited');
                QuickAlert.show(
                  context: context,
                  type: QuickAlertType.loading,
                  title: 'Loading',
                  text: 'Signing up',
                );
              } else if (state is UserCreated) {
                QuickAlert.show(
                  context: context,
                  type: QuickAlertType.success,
                  text: 'User created sucessfully', //state.message,
                );
              } else if (state is UserError) {
                QuickAlert.show(
                  context: context,
                  type: QuickAlertType.success,
                  text: state.error,
                );
              }
            },
            child: Form(...)

这就是我从用户那里调用我的事件的方式

context.read<UserBloc>().add(
        CreateUser(
          name: name,
          email: email,
          password: password,
          imageUrl: imageUrl,
      ),
   );

【问题讨论】:

    标签: flutter dart bloc flutter-bloc


    【解决方案1】:

    如果小部件没有更新,那是因为 bloc 认为发出的状态与前一个状态相同。

    我看到你扩展平等。

    Equatable 会为您覆盖 == 运算符,并使用 props 检查是否相等。 UserCreatingUserCreated 都返回一个空列表,因此 Bloc 可能没有看到任何变化。

    我会亲自覆盖== 运算符来检查对象类型。 如果您想继续使用 equatable,只需确保返回的 props 实际上不同。

    【讨论】:

    • 我还在 UserBloc 中发出 emit(UserCreated('User created successfully'),);emit( UserError(error.response.toString(),),);。如果我是对的
    • 我的错,我没有看到。我会更新答案。
    • 我正在尝试在 createUser 事件中打印一些内容,但没有打印任何内容。我还更新了代码以包含我如何从 UI 调用 createUser 事件
    • 您是否尝试过调试以确保正确添加事件?也许某些事情会默默地失败(异常不会向用户返回任何东西)。
    【解决方案2】:

    我看到你在外面的MultiBlocProvider 中提供了一个UserBloc

    BlocProvider(
        create: (context) => UserBloc(
           RepositoryProvider.of<UserRepository>(context),
        ),
    )
    

    那么你不应该将另一个新的UserBloc 传递给BlocBuilder,这将使BlocBuilder 听不同的UserBloc 实例,改变

    BlocListener(
       bloc: UserBloc(userRepo),
       listener: (ctx, state) {
    }
    

    BlocListener(
        listener: (ctx, state) {
    }
    

    【讨论】:

    • 删除它后,我收到Error: Could not find the correct Provider&lt;StateStreamable&lt;Object?&gt;&gt; above this BlocListener&lt;StateStreamable&lt;Object?&gt;, Object?&gt; Widget 的错误
    猜你喜欢
    • 2021-02-17
    • 2022-10-23
    • 2017-05-31
    • 2021-04-17
    • 2021-06-16
    • 1970-01-01
    • 2011-01-31
    • 2019-08-10
    • 1970-01-01
    相关资源
    最近更新 更多