【Riverpod学習】ref.watchとref.readとref.listenの使い分け
Riverpodでプロバイダの状態を操作・監視する際に使われるref.watchとref.readとref.listenについて学習したのでその備忘録です
以下のコードの例にref.watchとref.readとref.listenの使い分けを勉強します。
class TodoListView extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
// プロバイダの状態を監視
List<Todo> todos = ref.watch(todosProvider);
return ListView(
children: [
for (final todo in todos)
CheckboxListTile(
value: todo.completed,
onChanged: (value) => ref.read(todosProvider.notifier).toggle(todo.id),
title: Text(todo.description),
),
],
);
}
}
ref.watch:状態の監視
ref.watchは、プロバイダの状態を監視し、その状態が変化したときにウィジェットを再描画します。これは、プロバイダの状態をUIに反映させる場合に使われます。
主な特徴
リアクティブ:プロバイダが提供するデータが変わるたびに、ref.watchを使ったウィジェットやコードが再実行され、UIが更新されます。
再描画をトリガー:watchを使ったウィジェットは、プロバイダの状態が変わると自動的に再描画されます。
例
List<Todo> todos = ref.watch(todosProvider);
このコードでは、todosProviderが提供するList<Todo>を監視しています。もしtodosProviderの状態が変わると、このList<Todo>も更新され、関連するウィジェットが再描画されます。
使う場面
プロバイダの状態をUIに表示したい場合。
状態が変わったら、自動的にUIを更新する必要がある場合。
ref.read:状態の取得または操作
ref.readは、プロバイダの状態を一度だけ取得し、その状態を操作するために使います。readを使うと、その状態が変わってもウィジェットの再描画は行われません。
主な特徴
一度だけ取得:readを使う場合、その時点でのプロバイダの状態を取得するだけで、変更があってもその結果には反映されません。
操作に便利:状態を変更する関数(toggleやaddTodoなど)を呼び出す際によく使われます。
例
onChanged: (value) => ref.read(todosProvider.notifier).toggle(todo.id)
このコードでは、ref.readを使ってtodosProviderにアクセスし、そのnotifier(Todosクラスのインスタンス)を取得して、toggleメソッドを呼び出しています。これはタスクの完了状態を切り替えるための操作です。
使う場面
プロバイダの状態を使って一度だけ操作したい場合。
ボタンのクリックや入力など、ユーザーのアクションに応じて状態を変更したい場合。
ref.listen
- ref.listenはプロバイダの状態の変更をリスニングし、変更があったときに特定のコールバックを実行します。
- ウィジェット全体を再ビルドするのではなく、一度設定したコールバックで必要な処理だけを実行したい場合に使います。
- このコールバックは値の変化(成功、エラー、ロード中など)に応じて適切に処理を行うために便利
使い分けのポイント
ref.watch
- データを表示するために使用し、状態の変化に応じてウィジェットを再描画する。
- リアクティブな動作が必要な場合に使用。
ref.read
- データの操作や一時的な取得が必要な場合に使用。
- 再描画をトリガーしたくないときに使用。
ref.listen
- ウィジェット全体の再ビルドをせずに、プロバイダの状態変化に応じた適切な処理を行いたいとき
watchを使った状態の監視
List<Todo> todos = ref.watch(todosProvider);
ここでは、todosProviderを監視しているため、Todoリストに変更があれば自動的にUIが更新されます。
readを使った状態の変更
onChanged: (value) => ref.read(todosProvider.notifier).toggle(todo.id)
このonChangedハンドラでは、readを使ってプロバイダの状態を一度だけ取得し、toggleメソッドを呼び出しています。toggleメソッドがタスクの状態を変更しても、ここではウィジェットの再描画はトリガーされません。
まとめ
- ref.watch: プロバイダの状態を監視し、状態の変化に応じてウィジェットを再描画する。データを表示する際に使用。
- ref.read: プロバイダの状態を一度だけ取得し、操作を行う。再描画をトリガーせずに状態を変更したい場合に使用。
使い分けは、UIに反映させたいかどうかがポイントです。
Discussion