Riverpod: ProviderScope
CoddyのFlutterジャーニー「状態管理」セクションの一部。レッスン 16/27。
Riverpodは共有状態を扱うもう一つのパッケージで、Providerと同じ人が、学んだ教訓を活かして作りました。最大の変更点は、プロバイダーがウィジェットツリー内のウィジェットではないことです。ファイルの先頭、すべてのクラスの外にあるfinal変数です。
import 'package:flutter_riverpod/flutter_riverpod.dart';
final quoteProvider = Provider((ref) => 'Small steps, every day.');この関数がプロバイダーに値を与えます。Riverpodはウィジェットが初めて値を要求したときにこの関数を呼び出し、その結果を保持します。
値をどこかに保持しておく必要があり、その役割を担うのがProviderScopeです。main内でアプリ全体を囲むように、一度だけ配置します。
void main() {
runApp(const ProviderScope(child: MyApp()));
}ウィジェットはrefを通じてプロバイダーを読み取ります。ConsumerWidgetは、buildがref.watch(quoteProvider)を受け取るStatelessWidgetです。その上にProviderScopeがなければ、この行は参照先がなく、アプリはNo ProviderScope foundというエラーで停止します。
チャレンジ
簡単アプリがNo ProviderScope foundで停止します。
mainでMyAppをProviderScopeで囲みます。- 引用文を
Small steps, every day.に変更します。
自分で試してみよう
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final appNameProvider = Provider((ref) => 'Daily Quote');
final quoteProvider = Provider((ref) => 'Write your quote here.');
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends ConsumerWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final appName = ref.watch(appNameProvider);
final quote = ref.watch(quoteProvider);
return Scaffold(
appBar: AppBar(title: Text(appName)),
body: Center(
child: Text(quote, style: const TextStyle(fontSize: 24)),
),
);
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
状態管理のすべてのレッスン
4Riverpod
Riverpod: ProviderScopeConsumerWidgetとref.watchRiverpod: StateProviderRiverpod: Notifier他のProviderを監視するProvider状態の置き場所を選ぶ自分で練習してみよう: Flutterオンラインコンパイラ