felangel / bloc

A predictable state management library that helps implement the BLoC design pattern
https://bloclibrary.dev
MIT License
11.53k stars 3.37k forks source link

question: Having a bloc inherit from a another bloc #4185

Closed Bonsai11 closed 3 weeks ago

Bonsai11 commented 4 weeks ago

I'm trying to have some kind of "base bloc" in my project, that contains logic that is needed for many different screens within the app. So the idea is to make several other blocs inherit from this base bloc, so they already have some of the required logic and events/states. Coming from Provider, this was easy to do and worked great. But with Bloc, I'm not sure if this is possible or recommended at all.

Simple example: class BaseBloc extends Bloc<BaseCounterEvent, BaseCounterState> class SomeOtherBloc extends BaseBloc

The inheriting Bloc would also have its event and state classes inherited from the BaseBloc. (This also raises the question how to pass the specific events and states types up to the actual Bloc class)

So basically my question is if this is possible and recommended at all? If not, how do I prevent having to write the same logic over and over again, as most of the screens in the app are going to need e.g. Load, Save events and e.g. Loading, Loaded, Saving states, while also adding custom ones.

Regards

felangel commented 3 weeks ago

Hi @Bonsai11 👋 Thanks for opening an issue!

Based on your description, it sounds like you should be able to create generic states and events and have multiple blocs use the shared events and states.

For example:

sealed class AsyncState<T> {
  const AsyncState();
}

class Loading<T> extends AsyncState<T> {
  const Loading();
}

class Success<T> extends AsyncState<T> {
  const Success({required this.value});

  final T value;
}

class Failure<T> extends AsyncState<T> {
  const Failure({required this.error});

  final Object error;
}

class CubitA extends Cubit<AsyncState<int>> {
  CubitA() : super(const Loading());
}

class CubitB extends Cubit<AsyncState<String>> {
  CubitB() : super(const Loading());
}

I generally don't recommend having mutliple blocs extend a base bloc and instead recommend sharing logic via your repository layer, pure helper functions, and generic events/states as shown above.

Hope that helps!