【Flutter】RiverpodのNotifierProviderをカウントアプリでシンプル解説

Flutter状態管理

ジェネレーターを使い機会が多くなったFlutter×Riverpodの昨今ですが、使わないパターンも理解しより選択肢を増やすことができればRiverpodをアプリ開発で使う上でも便利だなと思いまとめてみました。

NotifierProviderとは

NotifierProviderとは、下記のようなものです。

  • NotifierというRiverpodの機能を使って状態を管理するプロバイダー
  • 同期の状態や状態の変更などが可能なプロバイダー

詳しく知りたい方は、以下の記事もぜひご確認ください。

Riverpodを使う上での注意

Riverpodのパッケージをpubspec.yamlにインストールする際に、2つのパッケージがありまるので注意が必要です。
flutter_riverpodとriverpodの2種類ですが、目的が少し違います。

  • riverpod: 純粋なDart用の状態管理ライブラリ
  • flutter_riverpod: Flutter用の状態管理拡張

test等シンプルな動作確認以外、基本flutter_riverpodをインストールのみでokです。

今回は説明を省略しますが、hooks×riverpodを使える”hooks_riverpod”というパッケージも存在します。

NotifierProviderを使用したアプリ実装

今回の内容

  • デフォルトであるカウンターアプリをnotifierで管理
  • UIや細かい設定は気にせず、「NotifierProviderの学習」にフォーカス
  • カウントの状態とカウントアップ/カウントダウンの2種類の関数providerで管理

UI実装

  • UI部分の実装
  • ref.watchでカウントの状態を監視
  • ref.read+関数でカウントアップ/カウントダウンを実施
class MyHomePage extends ConsumerWidget {
  const MyHomePage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final counter = ref.watch(counterProvider);
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '${counter}',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          // カウントアップのボタン
          FloatingActionButton(
            onPressed: () {
              ref.read(counterProvider.notifier).increment();
            },
            child: const Icon(Icons.add),
          ),
          // カウントダウンのボタン
          FloatingActionButton(
            onPressed: () {
              ref.read(counterProvider.notifier).decrement();
            },
            child: const Icon(Icons.remove),
          ),
        ],
      ),
    );
  }
}

Provider・Notifier実装

  • 初期値を0(int)のとして設定
    • build関数で管理するのがNotifierの基本状態管理方法
      • プロバイダーが初回 watch / listen されたときに一度だけ呼ばれる
      • ref を使って他のプロバイダーを参照したり、初期状態を外部データから取得可能
  • カウントアップとカウントダウンの関数を定義
    • stateはNotiferの実際の状態
    • それをインクリメントと減らす設定を実装
  • 上記2つの状態と関数を管理するためのProviderを定義
    • <Notifierクラス, 状態の型>を定義
    • 同じファイルで定義したCounterProviderを返す
class CounterNotifier extends Notifier<int> {
  @override
  int build() {
    // 初期値の設定
    return 0;
  }

  // カウントを増やす
  void increment() {
    state++;
  }

  // カウントを減らす
  void decrement() {
    state--;
  }
}

// 実際に値をハンドリングするProvider
final counterProvider = NotifierProvider<CounterNotifier, int>(() {
  return CounterNotifier();
});

まとめ

  • ConsumerWidgetを使用しref.watchで簡単に状態を管理可能
  • 1対多ファイルのような状態管理の時に便利
    • 今回のような1対1であればStatefulやHooksでも十分対応可
  • buildと各関数の定義で状態や状態変更のメソッドを管理

最後に

学習に特化したシンプルなアプリですが、NotifierProviderの基本を抑えるには良いかなと思います。
ご意見等ございましたらぜひTwitterにDMください。

ではまた。

コメント

タイトルとURLをコピーしました