Flutter
StateNotifierProvider
Provide StateNotifier with StateNotifierProvider.
What is StateNotifierProvider?
StateNotifierProvider is the Riverpod provider that supplies a StateNotifier to the widget tree. You access the state with ref.watch(provider) and obtain the notifier itself with ref.read(provider.notifier) to call its methods. The second generic parameter is the state type.
final counterProvider = StateNotifierProvider<CounterNotifier, int>(
(ref) => CounterNotifier(),
);
watch vs read
ref.watch rebuilds the widget when the state changes; ref.read does a one-time read and does not trigger rebuilds. That is why button onPressed handlers use read. If you mistakenly use watch, every click may trigger a rebuild.
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return ElevatedButton(
onPressed: () => ref.read(counterProvider.notifier).increment(),
child: Text('$count'),
);
}
Exercise Use a StateNotifierProvider
Define a StateNotifierProvider named counterProvider of type CounterNotifier with an int state. In main, create a ProviderContainer, call increment twice, and print the state.
Show example solution
import 'package:flutter_riverpod/flutter_riverpod.dart';
class CounterNotifier extends StateNotifier<int> {
CounterNotifier() : super(0);
void increment() => state = state + 1;
}
final counterProvider = StateNotifierProvider<CounterNotifier, int>(
(ref) => CounterNotifier(),
);
void main() {
final container = ProviderContainer();
container.read(counterProvider.notifier).increment();
container.read(counterProvider.notifier).increment();
print(container.read(counterProvider));
}
Test yourself
-
Which is used to update the state through a StateNotifierProvider?
- ref.read(provider).method()
- ref.notify(provider).method()
- ref.read(provider.notifier).method()
- ref.watch(provider).method()
Show answer
ref.read(provider.notifier).method() — Methods that mutate the state live on the StateNotifier itself, so you read it through provider.notifier.
-
Define a StateNotifierProvider
final counterProvider = StateNotifierProvider<CounterNotifier, int>(
(ref) => ____,
);
Show answer
final counterProvider = StateNotifierProvider<CounterNotifier, int>(
(ref) => CounterNotifier(),
);
-
StateNotifierProvider parts
- StateNotifierProvider
- Provides a StateNotifier
- ref.watch(provider)
- Listens to the state
- ref.read(provider.notifier)
- Returns the StateNotifier
- (ref) => CounterNotifier()
- The create function
Next lesson: AsyncValue