Chapter 08無料公開

各Providerの役割と使い分け

村松龍之介
村松龍之介
2023.02.23に更新
このチャプターの目次

RiverpodのProviderには以下のように複数種類あり、適材適所で使い分ける必要があります。

  • Provider
    最も基本的なProvider
  • FutureProvider
    非同期で取得した値を提供する
  • StreamProvider
    断続的に最新の値を提供する
  • StateProvider
    外部から変更可能な状態をシンプルに提供する
  • StateNotifierProvider
    外部から変更可能な状態と、状態操作メソッドクラスを提供する
  • (Async)NotifierProvider
    外部から変更可能な状態と、状態操作メソッドクラスを提供する。
    提供する値の型が Future であれば AsyncNotifierProvider を使用する。
  • ChangeNotifierProvider
    役割は `StateNotifierProviderと同様。推奨されていない

この章ではまず、最も基本的なProviderを解説します。
それ以外のProviderについては次章以降で一つずつ解説して参ります。


記事内のコードは分かりやすくなるよう一部省略しています。
完全なコードサンプルはこちらのリポジトリでご確認ください。
provider_page | flutter_app_template
https://github.com/altive/flutter_app_template/tree/main/packages/flutter_app/lib/pages/riverpod_example_page/provider_page

Provider - 最も基本的なProvider

(外部からは)変更できない値を公開できる基本的なProviderです。

また、別のProviderの値を加工して新たに別の値を返したいProviderなどにも使用します。

// Providerの定数をグローバルに宣言しましょう。
// このProviderの値の型は推論されてString型となります。
// 型を明示する場合: `Provider<String>((ref) => 'My TODO');`
final appNameProvider = Provider((ref) => 'My TODO');

// 〜中略〜

Widget build(BuildContext context, WidgetRef ref) {
  // Providerを監視し値を取得するには `watch` を使います。
  final appName = ref.watch(appNameProvider);

  return Scaffold(
    // Providerの値を使用して文字列を表示しています。
    appBar: AppBar(title: Text(appName)),
    body: ListView(
      children: [
        ...省略
      ],
    ),
  );
}

Providerの内部からは変更でき、 watch していれば、その変更は再構築を促します。

// 外部から変更可能なStateProviderを例に用います。
final counterProvider = StateProvider((ref) => 0);
// カウンターの値を2倍にした値を提供するProvider
final doubleCounterProvider = Provider((ref) {
  final count = ref.watch(counterProvider);
  return count * 2;
});

// 〜中略〜

Widget build(BuildContext context, WidgetRef ref) {
  // doubleCounterProvider を読み取る。
  // counterProvider の状態が更新されると doubleCounterProvider も変更され、再構築される。
  final doubleCount = ref.watch(doubleCounterProvider);

  return Scaffold(
    // doubleCounterProvider の値を表示
    body: Text('2倍されたカウント値:$doubleCount'),
  );
}