Menu
CoddyTech

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というエラーで停止します。

challenge icon

チャレンジ

簡単

アプリが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)),
      ),
    );
  }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

状態管理のすべてのレッスン

自分で練習してみよう: Flutterオンラインコンパイラ