世界最大級のオンライン学習サービス「Udemy(ユーデミー)」とは?

【flutter_riverpod】StateProviderの使い方|外部から変更可能な変数を任意のウィジェットに渡す

グローバルスコープで定義した変数を任意のウィジェットに渡したり、値を変更したりしたい

こんな時に便利なのが状態管理パッケージRiverpodの StateProvider ウィジェットです。

StateProviderを使用すれば外部から変更可能な変数を任意のウィジェットに渡すことができます。

それではStateProviderの基本的な使い方について解説していきます!

目次

パッケージのインストール

まずはRiverpodのパッケージをFlutterプロジェクトにインストールします。

ターミナルで次のコマンドを実行してpubspec.yamlファイルにflutter_riverpodを追加します。

flutter pub add flutter_riverpod

次にflutter_riverpodを使用するdartファイルに次のコードをコピペします。

import 'package:flutter_riverpod/flutter_riverpod.dart';

StateProviderの基本的な使い方

StateProviderの基本的な使い方について解説します。

ProviderScopeの追加

ProviderScopeのchildプロパティの引数にルートとなるウィジェットを渡します。

こうすることでchildに渡したウィジェットの下位ウィジェットでStateProviderを使用できるようになります。

void main() => runApp(ProviderScope(child: MyApp()));

StateProviderの定義

StateProviderはグローバルスコープ(クラスや関数の外)で次のように定義します。

final 変数 = StateProvider((ref) => 戻り値);
final stateProvider = StateProvider((ref) => 0);

void main() => runApp(const ProviderScope(child: MyApp()));

ConsumerWidgetで使用環境を整える

StateProviderをStatelessWidgetで使用したい場合には、StatelessWidgetの代わりにConsumerWidgetを使用します。

ConsumerWidgetは基本的にStatelessWidgetと同じですが、buildメソッドの第二引数にWidgetRefクラスのオブジェクトrefを渡します。

以後このrefを使用してプロバイダの値を取得・変更できます。

class MyWidget extends ConsumerWidget {
  const MyWidget({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return ...;
  }
}

StateProviderの値を取得

StateProviderの値を取得するにはrefのreadまたはwatchメソッドを使用します。

StateProviderで状態管理している値の変化を常に監視して反映させたい場合にはwatchメソッドが有効です。

final _counter = ref.watch(stateProvider);
class MyWidget extends ConsumerWidget {
  const MyWidget({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final _counter = ref.watch(stateProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('Flutter')),
      body: Center(
        child: Text(
          _counter.toString(),
          style: TextStyle(fontSize: 70),
        ),
      ),
    );
  }
}
画像のサンプルコード
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final stateProvider = StateProvider((ref) => 0);
void main() => runApp(const ProviderScope(child: MyApp()));

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyWidget(),
    );
  }
}

class MyWidget extends ConsumerWidget {
  const MyWidget({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final _counter = ref.watch(stateProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('Flutter')),
      body: Center(
        child: Text(
          _counter.toString(),
          style: TextStyle(fontSize: 70),
        ),
      ),
    );
  }
}

StateProviderの値を変更

StateProviderの値を変更するには次のようにupdateメソッドを使用します。

ref.read(stateProvider.notifier).update((変数) => 新しい値);
FloatingActionButton(
  child: Icon(Icons.add),
  onPressed: () {
    ref.read(stateProvider.notifier).update((state) => state + 1);
  },
),
目次