- 開発技術
【Flutter】Riverpod Tips
- Flutter
はじめに
【エンジニア募集中】フルリモート可◎、売上/従業員数9年連続UP、平均残業8時間、有給取得率90%、年休124日以上 etc. 詳細はこちらから>
この記事では、RiverpodのTipsを2つ紹介します。
1つ目は「FutureProviderをawaitする方法」、2つ目は「ref.refreshとref.invalidateの違い」についてです。
1. FutureProviderをawaitする方法
FutureProviderをそのままwatchした場合、戻り値はAsyncValueとなります。AsyncValueはdata, loading, errorの3つの状態をもち、これらの状態に応じて表示を切り替えるのには便利ですが、AsyncValueはawaitすることができません。データが使用できるまで待ち、その値を使用して後続の処理を行いたい場合は、.futureを使用してFutureProviderをawaitすることができます。
1 2 3 4 5 |
// AsyncValue は await できない final AsyncValue<User> user = ref.watch(userProvider); // .future を用いて、user が利用可能になるまで待つ final User user = await ref.watch(userProvider.future); |
future property – AutoDisposeFutureProvider class – riverpod library – Dart API
https://pub.dev/documentation/riverpod/latest/riverpod/AutoDisposeFutureProvider/future.html
The ref.watch method | Combining requests | Riverpod
https://riverpod.dev/docs/essentials/combining_requests#the-refwatch-method
また、プロバイダから必要なプロパティのみを読み取りたい場合、.selectを使用することが多いと思います。しかし、.selectはAsyncValueに適用されるため、awaitすることができません。FutureProviderのデータが使用できるまで待ち、特定のプロパティを監視したい場合は、.selectAsyncを使用してawaitすることができます。
1 2 3 4 |
// user が利用可能になるのを待ち、firstName プロパティのみを監視する final firstName = await ref.watch( userProvider.selectAsync((it) => it.firstName), ); |
selectAsync method – AutoDisposeFutureProvider class – riverpod library – Dart API
https://pub.dev/documentation/riverpod/latest/riverpod/AutoDisposeFutureProvider/selectAsync.html
Selecting asynchronous properties | Optimizing performance | Riverpod
https://riverpod.dev/docs/advanced/select#selecting-asynchronous-properties
2. ref.refreshとref.invalidateの違い
ref.refreshとref.invalidateはどちらもプロバイダを再計算したい場合に使用します。
この2つの違いについては、わかりやすく書くと「refresh = invalidate + read」となります。つまり、プロバイダの再計算後にその値を読み取るかどうかの違いです。基本的には、再計算後のプロバイダの値が必要であればrefreshを、不要であればinvalidateを使用するとよいと思います。
1 2 3 4 |
T refresh<T>(provider) { invalidate(provider); return read(provider); } |
ただ、挙動の違いについても注意する必要があります。refreshはinvalidateした直後にプロバイダを読むことで、プロバイダが即座に再計算されます。一方、invalidateは基本的に次のフレームの開始時まで更新が遅延されます。ただし、現在リッスンされていないプロバイダの場合は、再度リッスンされるまで更新されません。
Difference in behavior between ref.invalidate and ref.refresh · rrousselGit/riverpod · Discussion #2343
https://github.com/rrousselGit/riverpod/discussions/2343
What is the difference between ref.refresh and ref.invalidate? | FAQ | Riverpod
https://riverpod.dev/docs/essentials/faq#what-is-the-difference-between-refrefresh-and-refinvalidate
【エンジニア募集中】フルリモートも◎(リモート率85.7%)、平均残業8時間、年休124日以上、有給取得率90% etc. 詳細はこちらから>