【Flutter × Riverpod】AsyncValueのvalue / valueOrNull / requireValueの違い

こんにちは。エキサイトでアプリエンジニアをしている岡島です。

今回はFlutterでRiverpodを利用する時に扱うAsyncValueの3つのプロパティ

  • AsyncValue.value
  • AsyncValue.valueOrNull
  • AsyncValue.requireValue

について、それぞれの違いや特徴をまとめていこうと思います。AsyncValueにはさまざまなプロパティが用意されていますが、この記事ではvalue, valueOrNull, requireValueについて見ていきます。

環境

Flutter: 3.29.2
riverpod: 2.6.1

AsyncValueとは?

AsyncValueは、Flutterの状態管理ライブラリであるRiverpodに含まれるクラスで、非同期処理の結果を安全かつ簡潔に扱うために用意されている型です。

AsyncValueは以下の3つの状態を表現し、状態管理を簡単にしてくれます。

  • Data(データ): 非同期処理が成功し、データが利用可能な状態。
  • Loading(ロード中): 非同期処理が進行中でデータがまだ利用できない状態。
  • Error(エラー): 非同期処理が失敗し、エラーが発生した状態。

value, valueOrNull, requireValueそれぞれの違いについて

AsyncValue は、データの取得に一度成功した後に再度ローディングやエラー状態になることがあります(例:リフレッシュ時など)。その場合、過去(成功時)のデータを参照するケースがあるので、この記事では「初回の状態」としての挙動に焦点を当てて解説していきます。

value

try {
  final user = ref.watch(userProvider).value;
  return Text(user.name ?? '');
} catch (e) {
  return const Text('エラーが発生しました');
}
  • 成功時:値を返す
  • ロード中:null
  • エラー:throw

※ Riverpod 3.0 では、valueがvalueOrNullのように動作するよう変更されるみたいなので注意が必要です。 参考: 初期読み込み中にスピナーを表示し、エラーを処理する。

valueOrNullを使用して、現在のようにエラー/ローディング状態でvalueを使用します。 Riverpod 3.0 では、valueがvalueOrNullのように動作するように変更される予定です。 今はvalueOrNullを使用し続けましょう。

valueOrNull

final userAsync = ref.watch(userProvider);
final user = ref.watch(userProvider).valueOrNull;

if (user == null) {
  return Text('ローディング or エラー');
}

return Text('ようこそ ${user.name} さん');
  • 成功時:値を返す
  • ロード中:null
  • エラー:null

requireValue

final userAsync = ref.watch(userProvider);
// hasValue で事前にチェックしておくと安全です。
if (!userAsync.hasValue) return const SizedBox();

final user = userAsync.requireValue;
return Text('ようこそ ${user.name}');
  • 成功時:値を返す
  • ロード中:throw
  • エラー:throw

まとめ

プロパティ データあり ロード中 エラー時 特徴 throw
value null ❌ throw 明示的にtry-catchしたい時
valueOrNull null null UIで分岐したいときに便利
requireValue ❌ throw ❌ throw 絶対にデータがある前提なら

補足:AsyncValueには他にも便利なプロパティがある

今回紹介した value, valueOrNull, requireValue 以外にも、AsyncValue には以下のような便利なプロパティがあります。 - hasValue - hasError - isLoading - error - isRefreshing - adData - when - maybeWhen - map - maybeMap など

私はwhenをよく使っているのですが、他にもたくさん用意されているのでこれらを適切に使い分けれるようになりたいです。

# 最後に

今回は、FlutterでRiverpodを使った際に登場するAsyncValue の中で登場する3つのプロパティ
value, valueOrNull, requireValue の違いについて解説しました。 この記事が少しでも参考になれば幸いです!