Bloc: is it possible to yield 2 time the same state?

久未见 提交于 2020-05-17 08:40:45

问题


In the login view, if the user taps on the login button without having inserted his credentials, the LoginFailState is yield and the view reacts to it. If he taps again, this LoginFailstate is yield again, but the view doesn't react to it. So, is there a way to yield more times the same state?

There is some code to better explain my situation:

class LoginBloc extends Bloc<LoginEvent, LoginState> {
  @override
  LoginState get initialState => LoginUninitialized();

  @override
  Stream<LoginState> mapEventToState(LoginEvent event) {
    if (event is loginButtonPressed) {
      yield LoginFailState();
    }
  }

View:

 @override
  Widget build(BuildContext context) {
    return BlocBuilder(
      bloc: _loginBloc,
      builder: (BuildContext context, LoginState state) {
    if (state is LoginFail) {
        print ('Login fail');
    }
    return Column(
          ...
    )

回答1:


By default BLoC pattern will not emit state when the same state will be passed one after another. One way to do this is to pass your initial BLoC state after passing LoginFailState.

So after user clicks on the button with wrong credentials passed states will not be:

LoginFailState()
LoginFailState()

but

LoginFailState()
LoginEmptyState()
LoginFailState()
LoginEmptyState()

Which will make UI react to each of them.

But I think that the best and cleanest solution is to pass LoadingState from BLoC before passing LoginFailState().

You can follow the blog post that I have recently written regarding this topic.




回答2:


You can receive an update for the "same" State if you don't extend Equitable, or implement your own '==' logic which makes the two LoginFailStates equal.

The solution is to yield a different State in between, like in the Bloc example.

yield LoginLoading();

It gets called on every login button tap. Felangel's LoginBloc example.




回答3:


Use BlocListener to react to state changes.

    BlocListener(
      bloc: _loginBloc,
      listener: (BuildContext context, LoginState state) {
        if (state is LoginFail) {
          print('Login failed');
          // Or show a Snackbar
        }
      },
      child: BlocBuilder(
        bloc: _loginBloc,
        builder: (BuildContext context, LoginState state){
          // Your display code here
          return Container();
        },
      ),
    )


来源:https://stackoverflow.com/questions/56850693/bloc-is-it-possible-to-yield-2-time-the-same-state

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!