Why Choose Riverpod? — Accessing the Providers
This post is based off a presentation I did at Devfest 2023 in Cape Town on 23 Nov 2023. VIDEO | PRESENTATION
Previously we covered the extension methods provided by Riverpod, in this post we will take look at how we access these providers
UI
Some of you. may have notice the two references to “ref” in the examples in the previous parts of this series, similar to build context, that is how Riverpod accesses its providers. On the UI side you will have a WidgetRef
and within a Riverpod Provider you will simply use Ref
.
For the UI side we simply need to replace the StatelessWidget
with the ConsumerWidget
which will then add the WidgetRef
as the second argument on the widgets build method, from there we have access to many of the same accessors we would use with Provider
or BLoC
/ Cubit
. There is also a StatefulConsumer
widget as well as Hook versions available in a separate package for those who make use of flutter_hooks
.
// UI Side
class Widget extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final read = ref.read(operationsProvider(task.id));
final watch = ref.watch(operationsProvider(task.id));
final select = ref.watch(
operationsProvider(task.id)
.select((v) => v.first
);
final (first, second) = ref.watch(
operationsProvider(task.id).select(
(v) => (v.first, v.second),
),
);
}
}
For those not familiar, we have the read
which is used simply for accessing data from the provider, something which is advised against in the context of a widget as naturally any changes to the data will be ignored, so be careful when choosing to go this route and making sure the UI does not need to respond to changes.
watch
is, as the name suggest, a listener on the state and will trigger a rebuild whenever any piece of data within that state updates allowing the UI to reflect any of those changes.
Along with the watch
we also have the ability to use select
which will allow us to scope which values within the state the listener responds to. This provides a lot more control over what triggers the widget to redraw which can be handy in larger states and help with performance.
Classes
When it comes to accessing providers form within another provider, it is even more straightforward, here you would always be using read
which is accessed from the Ref
that is available within all Riverpod Providers.
class SharedNotifier extends StateNotifier<SharedState> {
final Ref ref;
final String id;
SharedNotifier(this.ref, this.id) : super(SharedState.initial());
Future<void> updateTaskStatus(TaskStatus status) async {
ref.read(sampleNetworkProvider)
..updateFlows(state.task, true, type)
..updateFlowStatus(state.order, status, type);
}
}
In the above code we are accessing one of our network providers and chaining a couple of methods onto that in order to fire off a set of API calls to update the status of the currently active task.
Next we will take a look at ProviderScope
the Riverpod widget that gives us most of it super powers.
I hope you found this interesting, and if you have any questions, comments, or improvements, feel free to drop a comment. Enjoy your development journey :D
Thanks for reading.
Originally published at https://remelehane.dev on March 12, 2024.