State management is a huge issue for the Flutter community. Coming from an Angular background I got accustomed to using Redux and therefore it made sense for me to follow the same pattern in Flutter. I also used services to encapsulate business logic and expose the state to the UI. It was a good exercise for me to try and emulate the same architecture in Flutter, especially with the emerging of the BLoC pattern.
The following article is my personal take on the matter, I don’t claim it to be the only way of achieving this architecture.
The BLoC pattern
The Business Logic Component pattern or as it is widely known the BLoC pattern is an architecture designed to decouple business logic from the view. It has helped teams to have a single codebase in regards to their business logic and expose them in various frameworks, most notable AngularDart and Flutter (like the Google Ads team).
In the BLoC pattern, you create a component that interfaces with the view only through Streams. This goes for all interaction either coming into the BLoC or coming out of it. The outgoing communication is straight forward as you only need to wrap your view Widget in a StreamBuilder and listen to the values coming out of the exposed outgoing stream.
For the incoming communication, you have to also expose a Sink in which the view will push events from the user. In your BLoC, you subscribe to the incoming Stream and delegate the action either to a private method or a Repository, if it is about fetching data.
What remains to be tackled is the state keeping as we really do not want to keep it in our BLoC.
Redux Store with BLoC
As we mentioned before the BLoC should not be responsible to keep the application’s state. It should delegate this responsibility to some other component dedicated to doing state management. In this example, we will use the Redux Store.
The BLoC could funnel events coming from the Sink to the Store as Actions and connect the application state from the Store to the Stream so that the Widget gets it.
The obvious benefit of using this approach is that if you do not have to change the BLoC’s API and thus no change in the UI (Widgets) is needed.
However, there is another approach that kind of breaks the BLoC all Streams contract. It uses methods for actions and getters for state subscribing. It is all made possible by the use of StoreConnector.
The BLoC pattern is a great way to encapsulate business logic and Redux is a great state management paradigm. Combining the two of them can create a clean logic layer in your application, which is going to help you tremendously in creating clean UI code.