メインコンテンツに進む

ProviderObserver

ProviderObserver は ProviderContainer 内で起こる変化を監視します。

ProviderObserver クラスを継承するクラスを定義し、使用したいメソッドをオーバーライドして使用してください。

ProviderObserver には3つのメソッドがあります。

  • didAddProvider はプロバイダが初期化されるたびに呼び出されます。公開される値は value パラメータで利用できます。
  • didDisposeProvider はプロバイダが破棄されるたびに呼び出されます。
  • didUpdateProvider はプロバイダが変更通知を送信するたびに呼び出されます。

使用方法

例えば didUpdateProvider メソッドをオーバーライドして、プロバイダのステート変化をログに残すという用途にも使用することができます。


// Riverpod を使用した Logger 付きのカウンターアプリの例

class Logger extends ProviderObserver {

void didUpdateProvider(
ProviderBase<Object?> provider,
Object? previousValue,
Object? newValue,
ProviderContainer container,
) {
print('''
{
"provider": "${provider.name ?? provider.runtimeType}",
"newValue": "$newValue"
}''');
}
}

void main() {
runApp(
// ProviderScope を置くことで Riverpod が有効になる
// Logger インスタンスを observers のリストに追加する
ProviderScope(observers: [Logger()], child: const MyApp()),
);
}

class MyApp extends StatelessWidget {
const MyApp({super.key});


Widget build(BuildContext context) {
return MaterialApp(home: Home());
}
}

final counterProvider = StateProvider((ref) => 0, name: 'counter');

class Home extends ConsumerWidget {

Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);

return Scaffold(
appBar: AppBar(title: const Text('Counter example')),
body: Center(
child: Text('$count'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => ref.read(counterProvider.notifier).state++,
child: const Icon(Icons.add),
),
);
}
}

これでプロバイダのステートが変化するたびに、Logger がログを取ってくれるようになりました。

I/flutter (16783): {
I/flutter (16783): "provider": "counter",
I/flutter (16783): "newValue": "1"
I/flutter (16783): }
注記

StateControllerStateProvider.state のステート)や ChangeNotifier のようにステートがミュータブル(可変)の場合は、 previousValuenewValue の値が変わることはありません。 それぞれ同じ StateController / ChangeNotifier を参照しているためです。