Reputation: 1600
I've been using RiverPod for a while now with Flutter, but I'm not sure what the best practice is for how to use RiverPod with a complex form.
Assume that I have a complex form that mas multiple text inputs., drop down selectors and radio buttons. For this I am using a Flutter 'form'' widget to manager validation and save actions. I have a model class that holds the data that is used to initiate the controls and capture the save action results.
Should I create a distinct RiverPod StateNotifier provider that uses the form model as its state, or should I keep the model data local to the form widget?
The downside of using a RiverPod StateProvider provider is that I have to create a 'setXXX' method in the StateNotifier for each data entry widget n the form. That way, when the form save action is called each data entry widget can call a related method in the StateNotifier to update its property into the model
Any suggestions?
Upvotes: 1
Views: 1639
Reputation: 179
You shouldn't use Riverpod for local widget state. So for things like forms and animations, use flutter_hooks. Using Riverpod for forms can be tedious. If I'm correct, Remi Rousellet himself doesn't recommend doing that.
For forms, I would recommend keeping the state local to your widgets (possibly using hooks if that's your thing). And put the state inside providers only on submit after it has been validated
https://riverpod.dev/docs/essentials/do_dont#avoid-using-providers-for-local-widget-state
https://github.com/rrousselGit/riverpod/discussions/2268
Upvotes: 0
Reputation: 31
So recommended way of dealing with complex form in a world of riverpod is using flutter_hooks which are independent of riverpod itself. So use riverpod when dealing with app global state stuff and hooks with widget based state. As far as I started to use the hooks I haven't written any stateful widget yet and there is a lot less boiler plate code.
In terms of forms what I tend to use alongside common form hooks(useState, useTextEditingController, useFocusNode...) is useValueNotifier where I pass complex object as starting point and update its value on any field change.
Upvotes: 0
Reputation: 44186
It's best to ignore the "legacy" providers like StateNotifier[Provider] now that Riverpod 2 is out. Yes, there's a lot of literature still referencing the legacy providers, and they do still work, but the modern unified interface for [Async|Stream]Notifier[Provider], and their ability to be generated from simple prototypes, makes them far preferable.
Upvotes: 0
Reputation: 4844
When data lies in widgets, it means that the interface is poorly separated from the business logic. If it turns out that this data has to change synchronously not only in this widget, but also in another widget, there will be duplication. On the other hand, the code will be shorter.
When changing each field entails calling the corresponding method in the StateNotifier
class, then ui is separate from the business logic - this is the right approach. But having a separate method to change each field can be tedious.
Assume what you expect from the project in the future. And make your decision based on that.
Also, you might want to look at the Freezed
package - it makes it easier to change the model with the copyWith()
field. Don't like code generators? There are great extensions in idea to generate these methods at the click of a mouse)
Upvotes: 0