BLoC Pattern in Flutter for Beginners (Part 1)

Bloc Pattern in Flutter, Header Image 1

If you are a Flutter Developer (or believe yourself to be one), you might’ve heard of BLoC as a State Management tool. Even if you haven’t this is the perfect tutorial to get an in-depth view of what it means and all about its abilities. In basic terms, BLoC stands for Business Logic and Component. In even simpler terms it just helps us separate Business Logic and the Components (UI). We will discuss this further in the first section. In this blog, we will be learning BLoC through a more visual aspect, the code part will be in the subsequent parts.

Prerequisites 🔮

Why use BLoC in Flutter? 🤔

The basic functionalities that BLoC tries to provide are:

  • State Management
  • Easier Testing
  • Manage Dependencies
  • Scalability of Codebase

As a beginner, you might be using setState((){}, Provider, RiverPod, GetX, or maybe some other State Management Solution. Those State Management Solutions are quite intuitive and easier to understand/implement, meanwhile, BLoC can be confusing for beginners and has quite some boilerplate code. But as we discussed, this all together makes our codebase easier to read, test, and locate bugs. BLoC is preferably used in large-scale projects where a number of developers will be working on the project because it is more scalable and easier to test. While it is inefficient to use BLoC in small projects, learning it can be very beneficial as it is used in several large-scale projects and is a common area for interview questions.

What is BLoC in Flutter 🤷‍♂️

To understand what BLoC is we will dive into the concept first and then we will look at its implementation details. Firstly, let’s understand how a normal application that uses setState for state management works.

Working of setState 🔰

Flow of application when it uses setState
App flow when using setState

In the Image above you can see that our User Interface interacts with the BackendService which is basically a class that handles the logic of let’s say making API calls and/or storing the data to the device. Just to create a sense of clean code in our User Interface we have created a BackendService which does that for us. The User Interface uses the functions inside BackendService to achieve tasks on specific interface events. It then uses the data to modify the State. Note, how State is tightly coupled to the User Interface.

The concept would be more clear if we look into the widget tree of the setState example.

Widget Tree when app uses setState
Widget Tree when using setState

The image above, better demonstrates how the local state works, Each UI Widget has its own state, and the Widget interacts with BackendService to update the current state. This is fine for small applications where you do not need to share the data among different widgets. However, in most applications, you do need a common data reserve that maintains the moment of truth for multiple widgets that depend on the same data.

NOTE: In the above examples, there is no shared state among the different Widgets

You might argue that creating a Singleton Class with the data would solve this problem, but I’m afraid that’s not the case. Firstly, it won’t be reactive meaning you will need the help of something that updates your widget tree about the data change, You might use Streams, ChangeNotifier, or ValueNotifier and ValueNotifierListener for that, it will work great! However, they are rarely used by themselves it’s common to integrate them with State Management solutions and then use them. In fact, the BLoC pattern heavily uses Streams. Never heard of Streams? Learn more about Streams in Flutter.

This is where multiple State Management Techniques come into place. The common idea is to lift the state up and inject it along the complete subtree. The idea of a singleton class is also a good example of lifting the state up, basically, we are creating a global instance for all widgets to refer up to.

Working of BLoC in Flutter 📦

Flow of application that uses BLoC in Flutter
The flow of an application that uses BLoC

In the above image, you can see how the responsibilities are divided among several components. Also note, how our State is not coupled to the User Interface it’s maintained by BLoC. Here’s a basic definition of each of the components:

  1. BLoC: Takes in Events from the User Interface like FetchData, ToggleFavorite and maps them to States like LoadedState, ErrorState etc. It interacts with Repository to perform the task itself, mainly it’s just mapping events to states.
  2. Repository: The repository is a class that contains several functions, its task is to interact with Data Provider. It’s not just an additional class as you may think. An app can have multiple Data Providers and the task of Repository is to bind them all together as needed and expose them as a function.
  3. Data Provider: Its main task is to provide data and perform operations on it. Be it making API calls, performing Firebase operations, interacting with Local Storage, etc.

Here’s how the Widget Tree would look while using BLoC:

Widget tree of application that uses BLoC in Flutter

In the Image, you can see how several widgets are using a Single BLoC as a source of truth. This is what we mean by lifting the state up. The BLoC is independent of any widget and is used across multiple widgets as the source of truth. To maintain a single instance of BLoC throughout the application we inject it into the Widget Tree, which we will discuss in the next part of this series.

TL;DR ⚡

BLoC is a state management pattern for Flutter that separates the business logic from the user interface. It does this by using a single Bloc class to handle all of the state changes in an application. The Bloc class has two properties: events and states. Events are triggered by the user interface, and states are the current state of the application. The Bloc class maps events to states, and it notifies the user interface of any state changes.

BLoC has several advantages over other state management patterns, such as setState. It is more scalable, as it can handle a large number of state changes without becoming too complex. It is also easier to test, as the Bloc class is independent of the user interface.

If you are developing a large Flutter application, BLoC is a good choice for state management. It is scalable, easy to test, and makes your code more maintainable.

Key Points 👇

  • BLoC is a state management pattern for Flutter.
  • It separates the business logic from the user interface.
  • It uses a single Bloc class to handle all of the state changes in an application.
  • The Bloc class has two properties: events and states.
  • Events are triggered by the user interface, and states are the current state of the application.
  • The Bloc class maps events to states, and it notifies the user interface of any state changes.
  • BLoC has several advantages over other state management patterns, such as setState.

This blog has also been posted to Medium, a clap would be appreciated!

Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post
Create a Vertical Timeline in React

How to create a Vertical Timeline View in React

Related Posts