Flutter Reactive Architecture with BLOC and MVI

Thais Aquino
4 min readApr 1, 2020

Flutter is relatively new and searching for best practices can be a hard work of researching for good references and choosing to adopt what makes more sense.

First I started using Redux in some side projects and at work as well. But as long as I was getting more comfortable with Flutter and its resources, felt that I needed another step. I wasn’t happy with my unit testing and how the things were coupled and missed some aspects familiar to me from Android development world using a more Clean approach where I could be sure that each layer is independent and testable and having the code coverage looking more green 😄 And also wanted to get familiar with Dart Streams. Having the codebase more independent on platform and third parties libraries also became one goal thinking about possibilities to share code between different platforms.

I started studying BLOC and used some good references as these recommended from the official documentation.

In this post I will go through one solution that I could come up with and will explain step by step the core implementation.

With BLOC the concepts of inputs and outputs come in handy when we can ally with MVI that is orchestrated by intentions. So in the solution that will be presented there are Intentions as Inputs and Outputs that are the corresponding state that will dictate how the UI will behave.

Overview of all elements in the MVI reactive approach:

Partial State

Represents the Intentions that can be user inputs in the View.

View State

Represents the recipe on how the UI must behave after receiving results from some processing.

Presenter/ BLOC

Presenter holds StreamController that orchestrate the data being streamed between the UI and the business logic behind. Also holds the combination between intention and reaction.

View

The view holds an initial state and all the possible triggers that can start a processing, then emit the results through the stream to update the UI state. Our widgets will be gaining View powers in this Flutter implementation.

StreamBuilder to render the states in the UI and recreate the Widgets on each state emitted

StreamBuilder listen to the presenter stream and rebuild the widgets in case there is a new state emission.

Going through the code

Views and Presenters implements MviDisposable. We need to dispose them when they are no longer needed.

Every View must have an initial state to first start the streaming of data that will dictate how the UI must behave.

PS — Partial State (MviPartialState). Represents the Intentions/Actions.

VS — View State (MviStateViewModel). Represents the corresponding State of the Intention/Action.

MviPresenter is where most of the magic happens:

Here is the link for the repo with the complete code and example: https://github.com/tasaquino/mvi_flutter_example

In the Part 2 we will go through the example that consumes this MVI implementation.

Thank you for reading and see you all in the next part 😉

--

--

Thais Aquino

Senior Software Engineer (Flutter | React Native | Android | iOS)