55 Riverpod (Understand)
Q: So, essentially the riverpod’s “Provider” provides:
- Notifier: give state and methods to operate on state.
- WidgetRef: give methods (like
watch()
,read()
) for the consumers to know when to rebuild (withwatch()
) and what notifier method to notified when callback was involk (withread()
)
Am I understand correctly?
Yes, you’re understanding it correctly! Let me clarify and expand on your understanding:
55.1 Riverpod’s Provider System
You’re right that the Provider gives you access to two main things, but let me refine the explanation:
55.1.1 1. The Notifier (State + Methods)
// The provider gives you access to the CounterNotifier instance
final counterProvider = StateNotifierProvider<CounterNotifier, int>((ref) {
return CounterNotifier(); // This is the notifier
});
// Access the notifier to call methods
.read(counterProvider.notifier).increment();
ref// ^^^^^^^^
// Gets the CounterNotifier instance
55.1.2 2. WidgetRef (Consumer Interface)
class CounterDisplay extends ConsumerWidget {
@override
, WidgetRef ref) {
Widget build(BuildContext context// ^^^^^^^^^^^
// This is WidgetRef
// WidgetRef provides these methods:
final count = ref.watch(counterProvider); // Subscribe & rebuild
.read(counterProvider.notifier).increment(); // One-time access
ref
return Text('$count');
}
}
55.2 Visual Breakdown:
┌─────────────────────────────────────────────────────────────┐
│ Provider System │
│ │<CounterNotifier, int> │
│ StateNotifierProvider
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Provides │ │
│ │ │ │1. Notifier Instance (CounterNotifier) │ │
│ │ : int │ │
│ │ ├── State: increment(), decrement(), reset() │ │
│ │ ├── Methods
│ │ └── Business Logic │ │
│ │ │ │2. Access Interface (via WidgetRef) │ │
│ │ .watch() - Subscribe to changes │ │
│ │ ├── ref.read() - One-time access │ │
│ │ ├── ref.listen() - Side effects │ │
│ │ └── ref
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
│ Used by ConsumerWidgets
▼
┌─────────────────────────────────────┐
│ ConsumerWidget │
│ │, WidgetRef ref) { │
│ build(context// Access state │
│ final count = ref.watch(provider); │
│
│ │// Access methods │
│ .read(provider.notifier) │
│ ref.increment(); │
│ } │
│ └─────────────────────────────────────┘
55.3 Key Points:
55.3.1 WidgetRef Methods:
// ref.watch() - Subscribes to changes, rebuilds widget when state changes
final count = ref.watch(counterProvider);
// ref.read() - One-time access, no rebuilds, used for calling methods
.read(counterProvider.notifier).increment();
ref
// ref.listen() - For side effects (navigation, showing snackbars, etc.)
.listen(counterProvider, (previous, next) {
refif (next > 10) {
.of(context).showSnackBar(
ScaffoldMessenger: Text('Count is over 10!')),
SnackBar(content
);}
});
55.3.2 Two Different Access Patterns:
// 1. Access STATE (for display)
final currentCount = ref.watch(counterProvider);
// ^^^^^^^^^^^^ ^^^^^^^^^^^^^
// Gets the int Returns current state value
// 2. Access NOTIFIER (for actions)
.read(counterProvider.notifier).increment();
ref// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Gets CounterNotifier instance and calls method
55.4 Complete Flow:
- Provider creates and manages the Notifier
- ConsumerWidget gets WidgetRef in its build method
- WidgetRef provides methods to interact with providers:
watch()
for subscribing to state changesread()
for accessing notifier methods
- When notifier methods modify state, Riverpod automatically notifies all watchers
- Widgets that
watch()
the provider rebuild with new state
So yes, your understanding is spot on! The Provider system gives you both the state management (notifier) and the consumption interface (WidgetRef) to build reactive UIs.