由于 mapEventToState 的 Flutter bloc 迁移不工作

Flutter bloc migration due to mapEventToState is not working

我正在关注 migration 到新的 bloc 8.0.0。我正在尝试删除 mapEventToState 但我很难这样做。你能帮我怎么做吗?我已经在下面试过了,但是不行。

旧代码:

class SignInBloc extends Bloc<SignInEvent, SignInState> {
  final AuthenticationRepository authenticationRepository;
  final UserDataRepository userDataRepository;

  SignInBloc(
      {required this.authenticationRepository,
      required this.userDataRepository})
      : super(SignInInitialState());

  SignInState get initialState => SignInInitialState();

  @override
  Stream<SignInState> mapEventToState(
    SignInEvent event,
  ) async* {
    if (event is SignInWithGoogle) {
      yield* mapSignInWithGoogleToState();
    }
  }

Stream<SignInState> mapSignInWithGoogleToState() async* {
    yield SignInWithGoogleInProgressState();
    try {
      String res = await authenticationRepository.signInWithGoogle();
      yield SignInWithGoogleCompletedState(res);
    } catch (e) {
      print(e);
      yield SignInWithGoogleFailedState();
    }
  }
...

迁移代码(不起作用):

class SignInBloc extends Bloc<SignInEvent, SignInState> {
  final AuthenticationRepository authenticationRepository;
  final UserDataRepository userDataRepository;

  SignInBloc(
      {required this.authenticationRepository,
        required this.userDataRepository})
      : super(SignInInitialState())
  {
    SignInState get initialState => SignInInitialState();

    on<SignInWithGoogle>((event, emit) => emit(mapSignInWithGoogleToState()));
  }

Stream<SignInState> mapSignInWithGoogleToState() async* {
    yield SignInWithGoogleInProgressState();
    try {
      String res = await authenticationRepository.signInWithGoogle();
      yield SignInWithGoogleCompletedState(res);
    } catch (e) {
      print(e);
      yield SignInWithGoogleFailedState();
    }
  }
...

getter 不属于构造函数主体,我想它不再需要了。你可以这样解决问题:

class SignInBloc extends Bloc<SignInEvent, SignInState> {
  final AuthenticationRepository authenticationRepository;
  final UserDataRepository userDataRepository;

  SignInBloc({required this.authenticationRepository,
    required this.userDataRepository})
      : super(SignInInitialState()) {
    on<SignInWithGoogle>(_handleSignInWithGoogleEvent);
  }

  Future<void> _handleSignInWithGoogleEvent(
      SignInWithGoogle event,
      Emitter<SignInState> emit,
  ) async {
    // TODO do your thing and create and emit the SignInWithGoogleState
    emit(SignInWithGoogleState());
  }
}

注意,bloc v8 中的事件不再按顺序处理,而是并发处理。阅读此博客 post:https://verygood.ventures/blog/how-to-use-bloc-with-streams-and-concurrency

您的问题是 mapSignInWithGoogleToState() 正在返回 Stream 个状态,但是新结构需要在每次需要发出新状态时显式调用 emit

class SignInBloc extends Bloc<SignInEvent, SignInState> {
  final AuthenticationRepository authenticationRepository;
  final UserDataRepository userDataRepository;

  SignInBloc({required this.authenticationRepository,
    required this.userDataRepository})
      : super(SignInInitialState()) {
    on<SignInWithGoogle>(mapSignInWithGoogleToState);
  }

  Future<void> mapSignInWithGoogleToState(
      SignInWithGoogle event,
      Emitter<SignInState> emit,
  ) async {
    emit(SignInWithGoogleInProgressState());
    try {
      String res = await authenticationRepository.signInWithGoogle();
      emit(SignInWithGoogleCompletedState(res));
    } catch (e) {
      print(e);
      emit(SignInWithGoogleFailedState());
    }
  }
}

这里有一些关于“为什么?”的更多信息:https://bloclibrary.dev/#/migration?id=rationale-6