Flutter Bloc : A Complete Guide to State Management in Flutter

Learn how Flutter Bloc, a powerful state management library, simplifies the separation of business logic from the user interface in Flutter app development. 

Understand the core concepts of EventsBLoCs, and States to effectively manage your app's state and improve code organization.

Flutter Bloc, State Management, Business Logic Component, Flutter Development

What is flutter bloc? Flutter bloc is one of the state management for Flutter applications. You can use it to handle all the possible states of your application in an easy way.

In this article, I am going to explain about Bloc. Bloc is not just a state management, but it's also an architectural design pattern which helps us to build production-level applications.

  • What is Bloc and its Architecture? 
  • What is BlocBuilder, 
  • BlocProvider,
  • BlocListener, 
  • BlocConsumer, 
  • RepositoryProvider? 
  • Folder Structure For Bloc


When it comes to building an application, 

Flutter is the easiest and powerful framework.

But building an application without any strong architecture is like building a house without any planning and blueprints.

  • You won't understand the uses of architecture when building small applications.
  • But when it comes to building a big production level application where you have many screensanimationsmethodsclasses, etc, without any proper architecture you will end up in a state where everything is messed up and you don't know how all the components, classes, methods are communicating and functioning.

So it is very necessary to maintain the code make code more readable and testable, and easily trackable when designing and developing this kind of big application.

There are many different packages available, and all have their own way to handle application states.

Why bloc?

In this article, I am going to explain about Bloc. Bloc is not just a state management, but it's also an architectural design pattern which helps us to build production-level applications.

Bloc stands for Business Logic Component.

In computer software, business logic or domain logic is the part of the program that encodes the real-world business rules that determine how data can be created, stored, and changed.

Bloc separates the UI from the business logic. When we build an application without any architecture, we most probably write our logic directly inside the UI. 

But when we use Bloc we have to write the business logic in a separate file, i.e separated from UI and then we link it to the UI.

Bloc makes the application easily testable, fast, reactive.

The Bloc is distinguished into four layers 

  • UI (Presentation Layer) 
  • Bloc (Business Logic Layer)
  • Data Layer (Repo Data Provider ) 

UI (Presentation Layer) :

All the component(Widgetsof the app which is visible to the user is defined here.

Bloc (Business Logic Layer):

It acts as a middle man between UI and Data layer, Bloc takes an event triggered by the user (ex: GetWeatherData button press, Submit form button press, etc) as an input, and responds back to the UI with the relevant state.

Data Layer

This layer has further two parts

Repository and Data Provider.

  • Data Provider - This layer retrieves/fetches the raw data from different data sources (ex: different APIs, DBs, Network, Shared preferences, etc). 
For example: If you are building a weather app. Then you might use external APIs like OpenWeatherAPI, from where you will get raw data. You can have GET, POST, DELETE, etc methods inside this class. For example, To get the raw data from OpenWeatherMap API we can do something like

  • Repository - : The repository layer acts as an intermediary between the data sources (such as APIs, databases, or local storage) and the business logic layer. It abstracts away the details of how data is fetched and provides a clean API for the business logic to retrieve data. 
(For ex: converting the raw into some kind of Model). 

Bloc communicates with this layer when the user requests the data. This layer requests raw data from the Data Provider and after that, this layer performs some kind of transformation. 

For example, converting raw weather data to WeatherModel.

This Repository layer directly communicates with bloc in order to pass data

The above figure is showing exactly how every layer is communicating with each other.

There are two very important terms that you need to understand : Event and State.

Event is nothing but different actions (button click, submit, etc) triggered by the user from UI. It contains information about the action and gives it to the Bloc to handle.

The UI will update according to the State it receives from the Bloc. For example, there could be different kinds of states
  • LoadingState - Will Show Progress Indicator
  • LoadedState - Will Show Actual widget with data
  • ErrorState - Will show an error that something went wrong.

Bloc Widgets 
These are widgets that the library provides you to manage all the possible cases, for example, add an event, listen to a state, emit a state, rebuild the view depending on the state, and so on.


BlocProvider is in charge of providing a bloc to its children. Is the way of “initializing” the bloc before using it.

If you need to provide more than one bloc you can use the MultiBlocProvider to get different providers.


RepositoryProvider is used to provide a repository to its children. 

Normally you are going to use it when you need to create an instance of your repository class and then with the BlocProvider, you are going to access that repository with help of context.read<YourRepository>();

This is an example.

If you need multiple repositories providers you can use a MultiRepositoryProvider.

Listens to state changes and calls a listener function for side effects. Doesn't rebuild the widget itself.
You need to perform actions that don't directly affect the UI, like navigation, showing snackbars, calling external services, or managing local data.

Use BlocListener to handle these actions in the listener function without rebuilding the UI.

Rebuilds the widget with new data whenever the bloc's state changes. Has access to the full state.
You need to display data directly from a bloc's state.

Use BlocBuilder to build the UI based on the state and update it automatically when the state changes.

Combines the functionality of BlocListener and BlocBuilder. Can listen to state changes and rebuild the widget. Has access to the full state.
You need to both perform actions and rebuild UI in response to state changes.

Use BlocConsumer to handle both UI updates and side effects within the same widget.

Rebuilds the widget only when a specific part of the bloc's state changes, as determined by a selector function. Optimizes performance for large state objects.
You only need a small part of a large state object in a widget, and you want to avoid unnecessary rebuilds.

Use BlocSelector to extract the relevant part of the state and only rebuild the widget when that part changes.

Hope you enjoy it 😊