is built on top of Flutter's and has been marked as a Favorite package by Flutter. It simplifies the code required when using Provider and is currently one of the best state management solutions for Flutter.
Bloc may seem complex for beginners, but compared to simpler state management solutions like , Bloc offers better screen rendering optimization and more convenient state management. Both Bloc and are based on Provider, so you can choose a state management tool based on your preference. Bloc also provides a simpler state management approach called , making it beneficial for both small-scale and large-scale projects.
For large-scale projects, Bloc is commonly used (), but it requires writing a significant amount of code. To address this, Mason can be used as a solution. I will explain how I automate my Bloc code templates in the next section.
In addition to state management, Bloc offers other useful features that I frequently use, such as:
Caching and persisting Bloc states, which is useful for storing application settings.
Redo and Undo functionalities for state transitions.
For more details, refer to .
Code Faster with Mason
You can check out my Bloc template at and create one for yourself. If you are not familiar with Mason, refer to this guide: .
Most of us get used to a specific coding style, but when switching to different projects, rewriting everything from scratch slows down development. For simple modules, Cubit is a great choice, but for larger and more complex modules, we need a more structured and explicit state management approach.
My Bloc Structure
I organize my Bloc into a single folder with two main parts:
Bloc for handling state logic.
Event and state combined into a single file (since they are not too long), reducing unnecessary files.
This structure allows us to define state enums or default app settings at initialization.
Make sure to explore Bloc extensions for IDEs like Android Studio to speed up your development process. You can also create live templates to reuse frequently used code snippets efficiently.
Debugging and Logging Bloc Events
This feature is already covered in the Bloc documentation. Typically, it's only necessary for critical Blocs where you need to monitor event flow or debug errors.
/// Logging state area
@override
void onChange(Change<{{name.pascalCase()}}State> change) {
super.onChange(change);
// myLog.trace(change);
}
// capture information about what triggered the state change
// Learn more: https://bloclibrary.dev/bloc-concepts/#:~:text=One%20key%20differentiating,overriding%20onTransition.
@override
void onTransition(Transition<{{name.pascalCase()}}Event, {{name.pascalCase()}}State> transition) {
super.onTransition(transition);
myLog.trace(transition);
}
@override
void onEvent({{name.pascalCase()}}Event event) {
super.onEvent(event);
// myLog.trace(event);
}
@override
void onError(Object error, StackTrace stackTrace) {
myLog.trace('$error, $stackTrace');
super.onError(error, stackTrace);
}
Another way to always listen to these changes without writing them into each individual Bloc is available.
Here is an example of how I can access context from anywhere:
final isUsageTimeLimit = myNavigatorKey.currentContext!.read<SettingBloc>().state.setting.otherSetting.isUsageTimeLimit;
Check out my article on accessing context anywhere here to learn how to set it up.
My Bloc is designed as part of the MVVM architecture, where the UI communicates directly with the Bloc. The Bloc is responsible for retrieving data from repositories. You can explore the official Bloc architecture . If you want to implement it within a clean architecture, check out this article: .
I also use to facilitate state persistence using hydrated_bloc and replay_bloc.
To save the Bloc state to device storage for the next app launch, refer to:
🔗
Make sure to initialize HydratedBloc after the app has fully loaded.
If you're not using MyFlutter, replace it with the appropriate storage directory for your project.
More details:
This is how I use Bloc in my projects. You can adapt it to create your own code template that fits your projects, helping reduce development time while still leveraging the full power of Bloc.
|