ジェネレーターを使い機会が多くなった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
を使って他のプロバイダーを参照したり、初期状態を外部データから取得可能
- build関数で管理するのがNotifierの基本状態管理方法
- カウントアップとカウントダウンの関数を定義
- 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ください。
ではまた。
コメント