Flutter state management

You key in your username and password on a login page, and then you press the login button.

You don’t see the app doing anything but behind the scenes, it’s authenticating the credentials and redirecting you to the home page.  

Like most users, you’d probably think that the app is either lagging or that it’s just buggy and broken. 

State management exists to prevent this very scenario from happening. 

Good state management is a crucial component of any frontend project as it reflects the changes in the user interface, and it always keeps the user in the loop of any state changes. It ensures that the user has a smooth experience while using the app.

In the world of Flutter, state management has been evolving swiftly, and there are a few different options for you to choose from. Some are native to Flutter itself while others borrow ideas from the other popular frameworks. 

Picking the right type of state management is definitely crucial to your project. A few notable state management options you could choose from:

1.SetState
2.InheritedWidget
3.Provider
4.Bloc Pattern
5.Riverpod

We will be going through the list, and I’ll highlight the main pros and cons of each.

 

SetState

SetState is state management in its simplest form as it reflects the changes on the user interface. Whenever the SetState() function is called, the widget will be rebuilt. 

It is simple and straightforward but it is only good enough for simple uses such as changing the text of some field, etc. Once you start including complex business logic, setState() would quickly become underwhelming. 
 

Inherited Widget

Think of it as a Widget tree: Widget A is the parent of two child widgets; widget B and widget C. Both widget B and widget C will access the context of widget A. 

It looks promising, but it does come with some complexity. As the widget tree gets larger, it is easy to lose track of the context needed. Besides, it will also need a way to notify the widget to rebuild as the state changes.

We’d also need a root widget that contains all the other widgets so that they can access the context of widget A even though they’re not a direct child of widget A. 
 

Provider

The provider is one of the most implemented state management patterns. It is a wrapper of InheritedWidget for easier implementation, and it also improves reusability greatly.
 
In short, the Provider gives you a way to declare the context, and it is available for use anywhere you declare to watch and listen to it. 

After that, we can use the Consumer widget and get the context at the last widget in the widget tree. The provider class is implemented with a mixin name ChangeNotifier, where we’ll be able to call the notifyListeners() function.
 
Whenever the function is called, any widget that listens to it will rebuild the UI and reflect the new state. Thus, we do not need to look up the widget tree using a provider and get the context we need.

It is easy to use, fit for most use cases, from a simple app to an app that includes complex business logic.
 
It is powerful but it has a reasonably steep learning curve. Besides, it also comes with a few notable limitations like being able to access the nearest provider with the same type. You’ll end up having bloated code if you have a provider that relies on another provider. 
 

Bloc Pattern

Google first introduced the Bloc Pattern. 

The core concept for Bloc is to separate the UI, business logic, and data services. So it was a big hit when it was introduced and it’s curated by the official Flutter team.

UI -> Bloc (Business Logic) -> Repository -> Data Provider.

Bloc is where all the business logic lies. The repository layer will decide which data provider to use to abstract away from tying to a single data provider. The Data Provider layer would have the APIs to retrieve the necessary datasets, similar to how RxJs works.

Bloc is arguably the state management that ticks all the boxes. It is a good choice for a large development team, where the business logic, the data provider are all properly separated. 

However, the major pain point for Bloc is too many boilerplates. Also, it might be overkill for a small-scale app.
 

Riverpod

Riverpod appears to be the biggest game-changer to Flutter’s state management, and it has been gaining huge momentum since it first launched. 

Riverpod is a complete rewrite of the Provider and it aims to eliminate all its limitations. Riverpod received a warm welcome from React developers as it conceptually works like the React Hook and Provider, as we stated above.

It is easy to implement, suitable for different scales of an app. While tons of excellent community tutorials are available online, it is not difficult to follow one and implement it. Though it is a stable version now, it is still in a rapid development growth stage. Therefore, expect major changes and vast improvements.

 

Conclusion

There are tons of state management solutions for Flutter. It is worth spending some time to find one which best fits the application’s requirements before implementing it. Personally, I started my journey from setState() to Bloc, to Providers, and now I use Riverpod.
 

 


Popular posts

Archives