由于mapEventToState不起作用而导致的Flutter块迁移

hivapdat  于 2023-01-14  发布在  Flutter
关注(0)|答案(2)|浏览(151)

我正在迁移到新的块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();
    }
  }
...
oprakyz7

oprakyz71#

您的问题是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-8

ivqmmu1c

ivqmmu1c2#

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中的事件不再是按顺序处理的,而是并发处理的。https://verygood.ventures/blog/how-to-use-bloc-with-streams-and-concurrency

相关问题