RJB
RJB

Reputation: 1924

Riverpod Flutter: Multiple providers for one screen

I'm new to riverpod, and I want to check that I am doing things correct.

I have a screen on my Flutter app where the use inputs lots of information about a session. Like start time, end time, notes, duration, date etc etc. All this data in the end is stored in a dart complex object MySession(), will all the above properties.

My question is, in the meantime, I am creating a seerate provider for each field. Like this:

final selectedDateProvider = StateProvider((ref) => DateTime.now());
final sessionDurationMinutesProvider = StateProvider<int>((ref) => 0);

Now in the class, I call the providers like this in the build method:

selectedDate = ref.watch(selectedDateProvider);
sessionDurationMinutes = ref.watch(sessionDurationMinutesProvider);

Then I display them in the widgets.

When they are editing, I save the state like this:

ref.read(selectedDateProvider.notifier).state = datePick;

My question is, I have lots and lots of fields on this page. So I have to create lots of providers for each field. Is this the correct practise? Can I not make a customclass for all these fields, and then make one provider which will return this custom class?

On the riverpod docs it says: You should not use StateProvider if: your state is a complex object (such as a custom class, a list/map, ...) https://riverpod.dev/docs/providers/state_provider

I hope its clear!

Thanks

Upvotes: 1

Views: 4149

Answers (2)

Mike
Mike

Reputation: 509

You can define a single provider, and then use select to 'select' a single field. For example:

final configProvider = StreamProvider<Configuration>(...);

final productsProvider = FutureProvider<List<Product>>((ref) async {
final host = await ref.watch(configProvider.selectAsync((config) =>     config.host));

return dio.get('$host/products');    
})

In this example ( from here: https://riverpod.dev/docs/concepts/combining_providers )

You can listen only to a single field: in this manner you will minimize the number of refreshes because if the use changes a part of the state not 'selected' in your code, your page would not refreshed.

In your case I would make only a single provider with all fields, then in every part of your UI I would use select/selectAsync to load the single field. Moreover, because your are at first steps on Riverpod, I suggest you to see riverpod_generator: this package introduces a new 'language': you will create your providers using annotations @riverpod, take a look at the docs, it deserves to be used. (https://pub.dev/packages/riverpod_generator)

Upvotes: 1

mfkw1
mfkw1

Reputation: 1161

You already answered your question ;)

Yes, you can.

Make a class that will store the state of all the input fields and expose it through StateProvider.

To do it effectively you will probably need a copyWith method which can be written manually or generated. One of the possible approaches is to use freezed.

Upvotes: 0

Related Questions