CodeBlanks Logo Icon CodeBlanks

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'),
  );
}

Practice 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.

Starter code

main.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';

class CounterNotifier extends StateNotifier<int> {
  CounterNotifier() : super(0);
  void increment() => state = state + 1;
}

// counterProvider'ı tanımla
// CounterNotifier tipinde, int state tutsun

void main() {
  // ProviderContainer ile iki kez artır, yazdır
}

Sample solution

main.dart
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));
}

Expected output

2

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Which is used to update the state through a StateNotifierProvider?

  • ref.read(provider).method()
  • ref.notify(provider).method()
  • ref.read(provider.notifier).method() Correct answer
  • ref.watch(provider).method()

Explanation: Methods that mutate the state live on the StateNotifier itself, so you read it through provider.notifier.

2 Define a StateNotifierProvider

Question
final counterProvider = StateNotifierProvider<CounterNotifier, int>(
  (ref) => ____,
);
Answer
final counterProvider = StateNotifierProvider<CounterNotifier, int>(
  (ref) => CounterNotifier(),
);

Explanation: The create function returns a StateNotifier instance; it must be called with parentheses.

3 StateNotifierProvider parts

Term Meaning
StateNotifierProvider Provides a StateNotifier
ref.watch(provider) Listens to the state
ref.read(provider.notifier) Returns the StateNotifier
(ref) => CounterNotifier() The create function

All lessons in Advanced