- All Things Flutter
- Posts
- Why I use Riverpod as State-management for Flutter
Why I use Riverpod as State-management for Flutter
My long state-management journey is at an end it seems. Or that's what I hope at least.
The ugly side of Flutter
That there is no clear state-management solution from the Flutter team sucks. I mean, I get it. You have people from native development as well as web as well as beginners.
And state-management is done differently in every case. And I believe the Flutter team didn’t want to make the entry harder for some.
If we look at flutter.dev there are these options listed:
Provider
Riverpod
setState
InheritedWidget & InheritedModel
Redux
Fish-Redux
BLoC / Rx
GetIt
MobX
Flutter Commands
Binder
GetX
states_rebuilder
Triple Pattern (Segmented State Pattern)
solidart
flutter_reactive_value
Wow. Some of them I haven’t even heard off, and I use Flutter for more than 4 1/2 years professionally. This is 16 options.
And one of my favourites is even missing. 'Stacked’.
That’s definitely overwhelming for any beginner.
Why you should use state-management.
Because you want to give the users a nice experience.
handling network calls
asynchronisouly updating the UI
caching request to minimize api calls
error handling (because there will be things going wrong)
Imagine a simple App. That has 2 screens.
One is a list of recipes
And one is a list of favorites
Each recipe has a button to toggle a favorite. And the favorites list has a button to remove the recipe.
The recipe item and the favorite item are not on the same screen. So how do they communicate?
We could pass around the list of favorites, but that will make it harder to maintain if we extend the app.
The solution is to keep the state separate of the UI.
Like in the image below. The Favorites are saved in the blue circle.
This is not a tutorial about how to use state-management, but after all an opinionated article about why I use Riverpod, so let’s move on.
My 3 favorites
Riverpod
Stacked
Bloc
And here is why I don’t use 2 of them
Bloc
It just never felt right. I didn’t like the overhead of states and events. Made it just busy.
I see it a bit differently know, as I have used it in some projects, but I just still never felt at home.
Navigation used to be a hassle. Not sure if it’s fixed, but passing Blocs with Blocproviders etc. was just not super simple.
The verbosity of it was really the main drawback for me
And also the debugging, it just didn’t make that much sense in my head.
Stacked
Oh, how happy I was when I found it. Dane, the author had great tutorials. Written and in video form and I learned so much
Coming from native development, I felt at home with MVVM.
Here is a screen, there is the view model for it. Easy peasy.
I can’t pin point down exactly why I left it behind, but I felt, there was too much ‘magic’ going on behind the scenes.
Handling streams from Firebase was a bit awkward for me, and I ended up add rxDart all the time.
And it uses GetIt for DI. Nothing bad here, just another dependency.
Riverpod
It took me probably 1 1/2 years to fully understand how great it solves all my problems. The documentation used to be quite bad, but it’s continuously improving.
AsyncValue is just so good. Loading, error and data handling for every value.
It has almost no overhead.
With v2 the code generation takes away the difficult syntax.
Immutable state
It handles dependency injection
All parts of my apps are reactive
Cached network request are included
I can invalidate a provider and all the UI parts that are listening will react to the change.
Let’s look how cool Riverpod is
Ok, let’s say we have a Screen that wants to fetch a list of bars.
Here is the provider. That’s all the code.
A provider named barsProvider will be generated.
With a return Value of AsyncValue<List<Bar>>
And this is the screen that shows a list of bars.
ref.watch(barsProvider); listens to any change of the provider
in the beginning AsyncValue is loading. The app will show a loading indicator
after 1 second the call returns successfully and we show the bar list.
and we also handle the error case
And I personally wrap the loading and error cases in a generic widget, so I only have to handle the successful case. Here is the generic widget
And here is the simplified BarList Widget. Easy right?
The code above is actually from an MVP I’m working on. Here is a screenshot.
Let’s finish this up.
I don’t think there is a best solution. There are some that are not really great, because they want to do too many things at once.
Don’t worry too much about which solution to use.
The way I did it? I tried a couple of solutions and then just chose one that I now use for years. That’s when these solutions really start to shine.
When all the pieces of an app make sense in your head. And a new feature is so ridicously simple to implement.
That’s when you know you understand it.
For me it’s Riverpod. I will stick with it. And will promote it more and more.
Reply