I’m learning flutter and I was wondering how the state management works. At the moment I have a form in which I want to preview a selected image, selected country or a loader when submitted.
Not sure if the approach is correct though. I feel like this kind of state management should be done differently. Please, let me know if it’s okay to use state management or if it’s not, how should I approach such cases.
// Define a loader for the user profile update
final isLoadingProvider = StateProvider<bool>((ref) => false);
final selectedCountryProvider = StateProvider<String?>((ref) => null);
Let me share only the widgets I’m using the states on.
@override
Widget build(BuildContext context, ref) {
final isLoading = ref.watch(isLoadingProvider);
final selectedCountry = ref.watch(selectedCountryProvider);
... next part of the code
// Inside column widget's childrens
if (isLoading) const CircularProgressIndicator(),
TextFormField(
initialValue: selectedCountry ?? userProfile.country,
decoration: const InputDecoration(
labelText: "Country",
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
borderSide: BorderSide(color: textColor)),
hintText: 'Select a country'),
onTap: () => showCountryPicker(
context: context,
showPhoneCode: false,
onSelect: (Country value) {
ref.read(selectedCountryProvider.notifier).state = value.name;
},
),
),
2
Answers
Riverpod suggests to avoid using providers for local widget state. If there are multiple widgets in the same widget tree that need to access the state, you can put the state in the topmost widget (make it a state variable of a
StatefulWidget
‘sState
, or useuseState
from flutter_hooks) and pass down the state through parameters.If you really need shared state, then you can use
Notifier
instead, sinceStateProvider
is now discouraged. The most basic example of using aNotifier
for a shared state is shown in the homepage of Riverpod docs:If you don’t want to use code generator, you can define the provider and the notifier like this:
Form state should not be put inside providers.
Form state is local to UI widgets and tightly coupled with navigation. For example, if you have a form that spans over multiple pages, if the user presses "back" at a step, this should likely reset currently visible fields.
Or a user may quit a form, and re-enter it again later. Again, it probably would be unexpected to have the previous form state preserved.
As such, using providers for form state is undesirable.
The recommended solution is to use plain StatefulWidgets. Or if you wish to be fancy, use flutter_hooks, which is typically combined with Riverpod for animations or forms.