Chapter 12

ChangeNotifierProviderで状態を購読・操作する

村松龍之介
村松龍之介
2023.02.12に更新

ChangeNotifierProvider - 状態を保持し、操作できる

ChangeNotifier自体はFlutter SDKに内蔵されているクラスです。
状態とそれを操作するメソッドを同一クラスに書きます。
用途としてはStateNotifierと同じく「状態の保持と状態の操作」になります。

状態を変更しWidgetに伝達するさいは、 notifyListeners() を呼ぶ必要があります。

ChangeNotifierを継承したクラスを作成

Providerの作成の前に、必要なクラスを作成しましょう。

カウント数を保持するCounterクラスの例です。

class Counter extends ChangeNotifier {
  // 状態を定義・保持
  int count = 0

  // 以下は状態を操作するメソッド

  // `notifyListeners()` で状態(count)の変化を通知し、
  // `count` を使用しているWidgetの再構築が行われる

  void increase() {
    count++;
    notifyListeners();
  }

  void decrease() {
    count--;
    notifyListeners();
  }

  void reset() {
    count = 0;
    notifyListeners();
  }
}

Providerの宣言

作成した Counter のProviderを宣言します。

専用のファイルを作成して書いても良いですし、 class Counter の上に書いても良いと思います。

counter.dart
// ChangeNotifierProviderを定義
final counterProvider = ChangeNotifierProvider((ref) => Counter());

Widgetで使用する

counter_page.dart
// 〜中略〜 buildメソッド
Widget build(BuildContext context, ScopedReader watch) {
  // Providerを読み取る。watchを使用しているので、
  // `Counter` の状態が更新されるとbuildメソッドが再実行され、画面が更新される
  final counter = watch(counterProvider);

  return Scaffold(
    // 最新の `count` 数を表示
    body: Text('Count: ${counter.count}'),
    floatingActionButton: FloatingActionButton(
      // ボタンタップで Counterの `increase()` メソッドを実行
      onPressed: counter.increase,
      child: Icon(Icons.add),
    ),
  );
}

参考リンク

ChangeNotifier class | Flutter公式ドキュメント
https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html

Equivalent of ChangeNotifierProvider widget in Riverpod | StackOverFlow
https://stackoverflow.com/questions/64429471/equivalent-of-changenotifierprovider-widget-in-riverpod