Flutter: State matters... Complex stuff ahead
Last updated
Last updated
(By Sergio Guzmán and Juan David Vega)
Similar to web development, Flutter also has state management techniques based on Flux Architecture and Async information gathering. Here we have two of the most famous ones from the devs at Flutter
Just like its web counterpart, MobX on dart uses a Flux-like architecture
Taken from https://mobx.netlify.com/concepts
Let´s start looking at this triad by explaining the process of integrating a store with the avalable resources from MobX dart
Simple enough, a store is defined by to parts:
A codebase for the class with boilerplate code that supports the getters and setters of the values of the class ($_Counter)
An abstract class where observables (values that can change over time) and actions (methods to change the state of observables) are defined.
When first creating this class, the Flutter compiler will wonder where this "counter.g.dart" file is located. You only have to run the following command on the terminal to generate the file using mobx:
You need to instantiate the store outside your widget definition. Since MobX will handle the state of your app, your widgets will be Stateless.
Wherever you need the store data, put an Observer:
If you need to call an action, just use it as a regular method on your widgets
You can play with computed values (state derived from your observables):
You can also define reactions, that are event listener that get triggered when something happens to your observables. There are different flavors, like reacting to a specific value of the observable
This pattern makes use of Streams. You define a stream to handle your state, and StreamBuilder widgets to consume from your stream.
In reality you have to worry abouth the sinking and streaming
Taken from https://www.raywenderlich.com/4074597-getting-started-with-the-bloc-pattern
When using the BLoC pattern you need to take into account three things:
Definition of a stream that can be consumed by other components. If you want to define a Stream we recommend you to create a StreamController of the specific type of object you want to consume and exposing the stream from the generated controller. Something like this:
Always close the controller when you are done using the BLoC, meaning,
_myController.close()
Use the StreamBuilder widget to attach a stream to the widget tree. There are three important properties for a StreamBuilder:
stream: A stream to consume
initialData: Start data for the stream
builder: Given the data (stored in snapshot) and the context (variables depending on the screen or app flow) render a specific widget
It´s better for you to look at a concrete example:
Use sink when adding new data to the BLoC. This action will trigger a "data" event, meaning that something new was appended. This can be done easily from a StreamController
Also, if you are using Firebase Realtime database, then you might consider an approach based on this, since these kinds of databases are ultimately streams you can attach a StreamBuilder to, like so. You can also do more sophisticated subscriptions/streams management like this.
Flutter app architecture 101: Vanilla, Scoped Model, BLoC. This provides sample code and comparison for the three patterns.
When Firebase meets BLoC Pattern. BLoC with Firestore.
Flutter starting guide for BLoC Brian Kayfitz showcases a way in which you can organize your architecture using interfaces and inheritances inside a handson Restaurants example.
Building A Piano with Flutter. Recipient of The Flutter Create code quality mention. You can check out this contest for more inspiration.
Flutter with MobX simple review app. Short explanation of what MobX is and an example using observables and actions