Should You Use BLoC to Manage State in Flutter?

A three-part series about Flutter’s most popular state managers

Paul Vaneveld
Better Programming

--

Photo by Fabian Albert on Unsplash

In this three-part series, I’ll be making a side-by-side comparison of Flutter’s most widely used state managers.

There are a lot of tools out there, but a clear comparison between them is often lacking. This is a pity, since choosing the wrong state manager isn’t easily undone whence you start building.

Therefore I am offering you a short instruction manual. Read carefully before first use! The second most popular state manager, called Flutter bloc, is this blog’s subject. The link to the first part is found below.

What is the Flutter bloc?

The Flutter bloc package derives its’ name from the BLoC design pattern. BLoC is an abbreviation for “Business logic component” which — like most state managers — aims to decouple business logic from the views.

The Flutter bloc package provides you with all the tools to implement the BLoC pattern into your app. The core of the package revolves around the two main concepts “Cubits” and “Blocs”, which I will briefly explain.

Managing state with Cubit

Image from package:bloc documentation

Managing a state with Cubit may feel familiar to anyone who used a state manager before.

  • The state is stored and handled in a Cubit class. Furthermore, the Cubit exposes a stream of state changes.
  • BlocProvider makes the Cubit accessible to the view.
  • BlocBuilder listens to the changing state and renders the UI accordingly.

So managing the state of an incrementing counter, would look as follows:

This pattern is very similar to state management with Provider, which I described in the first part of this series. Therefore the real value of Flutter Bloc isn’t found in Cubit but in the actual Bloc itself.

Managing state with Bloc

Image from package:bloc documentation

The unique selling point of Bloc is events. A Cubit just sends state updates, without providing additional information about the root cause of the change.

As long as your state is simple, like in the counter example, this won’t be an issue. But suppose your counter could be incremented in 10 different ways. How are you going to debug unexpected state updates or differentiate your app's behavior based upon the change cause? In a nutshell, the lack of traceability poses a real problem.

// A Bloc transitionTransition {
currentState: Counter(0),
event: Increment,
nextState: Counter(1)
}
Transition {
currentState: Counter(0),
nextState: Counter(1)
}

Bloc solves this problem by introducing events. Events provide information about why the state has changed. Events give you full control over the flow of state of your application. Which, for apps that do more than incrementing a counter, is pretty desirable.

But every great gift comes with a price. Blocs are more verbose than Cubits. Additional boilerplate — shown in the example below — is needed for states and events. But, in my opinion, this is a price worth paying. In the long run, traceability is a precondition for the manageability of your app.

Who should use Flutter BLoC

So now you have a grasp of the Flutter bloc package, should you actually use it?

Pros

  • Being the second most popular state manager, the package is well maintained and has proved its value.
  • Providing nonevent bases Cubits as well as event based Blocs, the package adapts to your application demands.
  • There are plenty of ways to prevent redundant updates of the UI. Bloc state, for example, makes use of equatable. Equatable compares old state to new state and prevents updates when the state is unchanged. Furthermore, the BlocListener has a listenWhen property, which acts as a gatekeeper only granting access to desirable updates. In summary, the package provides tools to focus on the performance of your application.
  • The documentation is excellent, elaborating on way more than just the core internals. There’s room for extensive examples, the advantages, and disadvantages of an approach, best and bad practices, and background information about the package core concepts.

Cons

  • The sheer size of the Flutter Bloc package makes it hard to learn. When confronted with a large toolbox of quality tools, it can be hard to pick the right one for the job. The learning curve is especially steep for developers unfamiliar with streams and event-based state management.
  • The package has the dubious honor of needing the most boilerplate of all state managers. Especially event-based blocs are quite verbose. To set up the basic counter bloc mentioned before, you’d need three separate files: one for the counter’s state, one for the counter’s events and one for the actual Bloc. Although there are good extensions to automate boilerplate creation, your code base will still grow like a well fed toddler.

To conclude, Flutter bloc, in my opinion, is the way to go for most Flutter applications. It overcomes the lack of event based state management of Provider. Furthermore, its toolset is extensive, making it usable for simpler and more complex applications. These advantages make the steep learning curve worthwhile.

--

--

Developer who likes to share programming lessons learned along the way!