コンパイルセーフ
ProviderNotFoundException
の発生や、loading ステートを処理し忘れることを心配する必要はもうありません。Riverpod ではコンパイル可能なコードは有効なコードです。
制限のない Provider
Riverpod は Provider からインスパイアされていますが、その主要な問題を解決します。同じ型を値に持つプロバイダを複数作成したり、場所に縛られずにプロバイダを作成したり、といったことが可能になりました。
Flutter に依存しない
Riverpod は Flutter に依存することなくプロバイダを作成・共有・テストすることが可能です。 BuildContext
を使わずにプロバイダを利用することができます。
場所に縛られないステート宣言
main.dart
と UI 側のコードの間を行き来する必要はもうありません。
別のパッケージ内であろうと、ウィジェットのコードと同じファイル内であろうと、場所に縛られることなくステートを宣言することができます。これによりテスト容易性を損なうことはありません。
// A shared state that can be accessed by multiple
// objects at the same time
final countProvider = StateProvider((ref) => 0);
// Consumes the shared state and rebuild when it changes
class Title extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(countProvider);
return Text('$count');
}
}
ステートの再評価、UI の更新を最小限に
build
メソッドの中でリストをソート / フィルタする必要はもうありません。高度なキャッシュ手法に頼る必要もありません。
Provider
と "families" を使って、本当に必要な時に限ってリストのソートや HTTP リクエストを行えます。
final todosProvider = StateProvider<List<Todo>>((ref) => []);
final filterProvider = StateProvider<Filter>((ref) => Filter.all);
final filteredTodosProvider = Provider<List<Todo>>((ref) {
final todos = ref.watch(todosProvider);
switch (ref.watch(filterProvider)) {
case Filter.all:
return todos;
case Filter.completed:
return todos.where((todo) => todo.completed).toList();
case Filter.uncompleted:
return todos.where((todo) => !todo.completed).toList();
}
});
Bad state とは無縁
プロバイダの監視により Bad state エラーが発生することはありません。プロバイダを適切に利用することで、常に有効な値を取得できます。
これは非同期操作により値を取得する場合も同様です。Riverpod なら、loading/error のステートを簡潔に処理することができます。
final configurationsProvider = FutureProvider<Configuration>((ref) async {
final uri = Uri.parse('configs.json');
final rawJson = await File.fromUri(uri).readAsString();
return Configuration.fromJson(json.decode(rawJson));
});
class Example extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final configs = ref.watch(configurationsProvider);
// Use Riverpod's built-in support
// for error/loading states using "when":
return configs.when(
loading: () => const CircularProgressIndicator(),
error: (err, stack) => Text('Error $err'),
data: (configs) => Text('data: ${configs.host}'),
);
}
}
DevTools によるステートの検証
Riverpod では特別な設定をすることなく Flutter の DevTools でステートを検証することができます。
加えて、より本格的なステート検証ツールの開発が進行中です。
