What is the difference between Cubit and Bloc?

Solution 1:

Cubit is a subset of the BLoC Pattern package that does not rely on events and instead uses methods to emit new states.

So, we can use Cubit for simple states, and as needed we can use the Bloc.

Solution 2:

Cubit is perfectly suitable to any app scale. None of those is better than the other.

You have to chose between traceability and event sharing vs boiler plate.

Traceability

When you use a bloc you have a transition that contains the event:

Transition {
  currentState: AuthenticationState.authenticated,
  event: LogoutRequested,
  nextState: AuthenticationState.unauthenticated
}

When you use cubit it does not

Transition {
  currentState: AuthenticationState.authenticated,
  nextState: AuthenticationState.unauthenticated
}

That alone gives you traceability because you know which event triggered the changes just by looking at the logs. You see eventA happened then eventB. In practice though, for the cubit you can often infer traceability from the changes themselves without the "label", because there is not many action that can output this change. So I'd say in that area Cubit wins, because the extra traceability is often not worth the boiler plate cost.

Event sharing

In essence, emitting an Action/Event that is then mapped to call a function, is just like calling the function directly. The only fundamental change is when an action must be shared between multiple blocs that need to react to it. If action must be shared between blocs (example reset data on logout), then blocs can be handy in that area. However it might be a better architecture model not to mix one bloc with another, or it might not be, it depends. It's a judgment call here.

I'd say Bloc wins in the event sharing aspect. I'll also say that I don't think event sharing is good though because it widen the scope of a bloc-event. To me something above the bloc should be responsible of calling other blocs, but this is a personal opinion.

Solution 3:

The Cubit is suitable for simple State management where you just have one kind of event to bind to the state. While Bloc is for complex state management where you can have many events to map to states.

For example let consider below Cubit

class SimpleCubit extends Cubit<SimpleState> {
  SimpleCubit () : super(InitialState());
  
  void updateState(String stateName){
    emit(NewState(stateName));
  }  

}

Let now have a look on Bloc

class SimpleBloc extends Bloc<SimpleEvent, SimpleState> {
  SimpleBloc() : super(InitialState()){
    on<SimpleEven1>(_handleEvent1);
    on<SimpleEven2>(_handleEvent2)
  }

  Future<void> _handleEvent1(SimpleEvent event, Emitter<SimpleState1> emit) async {
   // Put your code here
   emit(SimpleState1(event.args))
}

  Future<void> _handleEvent2(SimpleEvent event, Emitter<SimpleState2> emit) async {
   // Put your code here
   emit(SimpleState2(event.args))
}
  
}

To implement above code with Cubit we will need switch cases (boilerplate)

Bloc force you to map each event to a separate function which is good when you have a complex state.