【问题标题】:Flutter Bloc - mapEventToState executes only onceFlutter Bloc - mapEventToState 只执行一次
【发布时间】:2021-12-05 00:33:42
【问题描述】:

大家好,

我是新来的颤振。我正在尝试使用 Bloc 进行简单的状态管理。我有一个主屏幕,根据状态显示/隐藏一些小部件。在一个单独的屏幕上,我有两个按钮,它们将事件添加到更新状态的流中,然后主屏幕上的小部件对状态更新做出反应。它工作正常,但 UI 仅在第一个事件之后重新构建,并且在后续事件中,该集团产生状态但 UI 不更新。同样在 main.dart Material App 中被 MultBlocProvider 包裹。我来自南非,所以我可能无法立即回复时区,但任何帮助将不胜感激。下面是代码sn-ps。

auth_state.dart

class AuthState {
  bool isLoggedIn = false;
}

auth_event.dart

enum EventType { login, logout }

class AuthEvent {
  late EventType eventType;

  AuthEvent.login() {
    this.eventType = EventType.login;
  }

  AuthEvent.logout() {
    this.eventType = EventType.logout;
  }
}

auth_bloc.dart

class AuthBloc extends Bloc<AuthEvent, AuthState> {
  AuthBloc(AuthState initialState) : super(initialState);

  @override
  Stream<AuthState> mapEventToState(AuthEvent event) async* {
    switch (event.eventType) {
      case EventType.login:
        AuthState newState = state;
        newState.isLoggedIn = true;
        yield newState;
        break;
      case EventType.logout:
        AuthState newState = state;
        newState.isLoggedIn = false;
        yield newState;
        break;
      default:
        throw Exception('Event not found $event');
    }
  }
}

home_page.dart (sn-p) -> bloc comsumer

 Padding(
   padding: const EdgeInsets.only(right: 30),
   child: BlocConsumer<AuthBloc, AuthState>(
     listener: (context, state) {},
     builder: (context, state) {
       return Visibility(
         visible: state.isLoggedIn,
         child: IconButton(
           key: HomePage.navigateToNotifications,
           onPressed: () {
             Navigator.push(
               context,
               MaterialPageRoute(
                 builder: (context) => Notifications()),
             );
           },
           icon: Icon(Icons.circle_notifications,
             size: 50, color: HexColor('27B88D'))),
       );
     }))

test_page.dart (sn-p) -> 触发 bloc 事件

          ElevatedButton(
              onPressed: () =>
                  BlocProvider.of<AuthBloc>(context).add(AuthEvent.login()),
              child: Text('Log User in')),
          ElevatedButton(
              onPressed: () =>
                  BlocProvider.of<AuthBloc>(context).add(AuthEvent.logout()),
              child: Text('Log User out'))

【问题讨论】:

    标签: flutter bloc


    【解决方案1】:

    我发现为状态声明单独的状态类而不是同一状态的新实例更容易。

    abstract class AuthState {}
    
    class NotLoggedIn extends AuthState {}
    
    class LoggedIn extends AuthState {}
    

    那么你的mapEventToState 看起来像这样

      @override
      Stream<AuthState> mapEventToState(AuthEvent event) async* {
        switch (event.eventType) {
          case EventType.login:
            {
              yield LoggedIn();
              break;
            }
    
          case EventType.logout:
            {
              yield NotLoggedIn();
              break;
            }
    
          default:
            throw Exception('Event not found $event');
        }
      }
    

    然后你的BlocConsumer 看起来像这样,它会按照你的预期重建

                Padding(
                  padding: const EdgeInsets.only(right: 30),
                  child: BlocConsumer<AuthBloc, AuthState>(
                    listener: (context, state) {},
                    builder: (context, state) {
                      return Visibility(
                        visible: state is LoggedIn ? true : false,
                        child: IconButton(
                            onPressed: () {},
                            icon: Icon(Icons.circle_notifications,
                                size: 50, color: Colors.amber)),
                      );
                    },
                  ),
                )
    

    【讨论】:

    • 很酷,谢谢,您的回答对您有所帮助,现在可以完美运行。 bloc 是颤振状态管理的理想模式吗?作为新手,我是否走在正确的轨道上?
    • 没问题。最佳状态管理可能是一个加载问题,因为关于它的讨论/争论太多了。 Bloc 绝对不会出错,如果你能理解它是如何工作的,那么你可能会发现其余部分更容易一些。我个人更喜欢 GetX,但同样,Bloc 很棒。我确实建议将 Bloc 更新到最新版本,因为它已经使用更简单的语法进行了更新。
    猜你喜欢
    • 2021-04-21
    • 2022-07-10
    • 2020-07-05
    • 2021-05-20
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    相关资源
    最近更新 更多