How To Manage State in Flutter With Provider
A three-part series about Flutter’s most popular state managers
Flutter is a cool new kid — or teenager by now — on the block. Google’s UI kit enables you to build native and performant mobile and web apps from a single codebase. Above that, the vast range of available widgets make for a fast and enjoyable development experience.
Being enthralled by Flutter's potential, I recently dove right into my first Flutter project. My enthusiasm didn’t fade. Flutter delivers on all its promises. But the opportunities a new tool provides, carry some risk in them as well.
When fiddling around with new toys, it’s generally a good idea to read the instruction manual. Since Flutter is only gaining traction a few years now, its instruction manual is still being written.
Clear and concise guidelines would have made my first Flutter project a lot better. Choosing the right tool for state management, in particular, was by no means an easy task. Options are plentiful, but a clear comparison between them is often lacking.
In my opinion, a comparison between state managers is much needed. Once your app’s state is entangled with a state manager, switching to another tool is not an easy task. So to help you get it right the first time, I’ll compare Flutter’s most popular state managers in a three-part series.
- Part 1: do you need a state manager and managing state with Provider
Do you need a state manager?
Before you start comparing the myriad state manager options, you should ask yourself:
“Do I even need a state manager?”
If your application is very flat by design and state rarely travels more than one level up or down the widget tree, passing state through properties and callbacks might save you a lot of boilerplate.
In the example below, the Child
is passed a callback from the Parent
to keep track of the number of times the TextButton
is clicked:
However, if you find yourself passing callbacks through multiple levels of the widget tree, managing state this way quickly becomes cumbersome and confusing. In this case, you can be sure you need a more powerful way of managing state. But what is the right tool for the job?
Managing state with Provider
There are plenty of options to manage your state in a Flutter app. Provider is one of the most popular state managers. This community created tool relies on three core concepts:
ChangeNotifier
: the store of your state from which state is updated and widgets consuming the state are notified.ChangeNotifierProvider
: this widget makes theChangeNotifier
accessible to underlying widgets in the tree.Consumer
: a widget that listens to state changes and updates the UI accordingly.
Below is an example of an updated click count using the Provider pattern:
- State is stored and handled by
DataProvider
class, which stores the_count
. - The
_count
is updated from theChild
widget by callingIncrementCount
on a button click. NotifyListeners()
makes sure theParent
widget, who accesses the state viaConsumer
, gets updated accordingly.
So, is Provider the best tool for state management?
Pros
- Well maintained and battle-tested package.
- Complete toolkit for unidirectional state management.
Cons
- With an impressive total of nine different providers, a proper understanding of Provider isn’t easily acquired.
- Unnecessary rebuilds aren’t easily avoided. By default
Consumer
updates all its child widgets, even if an irrelevant part of the state has been updated. Provider
is dependent upon the Flutter SDK, which makes your business logic and framework inseparable. This is considered a bad practice in architectural design.- State updates aren’t based on events. So in the example above, we know that
_count
has been updated, but we can only guess about the origin of the change. This complicates tracking and understanding state changes in your applications.
In summary, I think Provider
is a good choice for experienced Flutter developers who are building an app with simple state needs. Provider
is easy to learn but hard to master and, furthermore, lacks event-based state tracking needed for more complex apps.
In the next part of this series, I will be examining state management using the BLoC pattern.
Resources
- Flutter: https://flutter.dev/
- Flutter’s widget catalog: https://flutter.dev/docs/development/ui/widgets
- State management options for Flutter: https://flutter.dev/docs/development/data-and-backend/state-mgmt/options
- Provider package: https://pub.dev/packages/provider
- Nine different types of Providers: https://pub.dev/documentation/provider/latest/provider/provider-library.html