Riverpodの使い方と状態の破棄方法
こんにちは、株式会社Pentagonでエンジニアをしている阿久津です。
今回はRiverpod, Hookで状態管理を行う際に利用するChangeNotifierとその破棄方法について取り上げます。
登場するもの
- Widget(画面)
- ChangeNotifier(状態管理クラス)
- ChangeNotifierProvider(状態管理クラスへのアクセスを画面へ提供)
サンプル
(コメントを入れている行だけ着目)
// 1.状態管理クラスでChangeNotifierを継承
class SampleModel extends ChangeNotifier {
// 数値(状態)
int _num = 1;
int get num => _num;
void addNum() {
_num++;
// 5. 変更の通知して画面を更新
notifyListeners();
}
}
// 2.画面から状態管理クラスへのアクセス用のproviderを定義
final sampleProvider = ChangeNotifierProvider.autoDispose((ref) {
return SampleModel();
});
// サンプル画面
class SampleWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: HookBuilder(
builder: (context) {
// 3.Providerを利用して状態管理クラスを取得
final sampleModel = useProvider(sampleProvider);
return Center(
child: Column(
children: [
// 数値の表示
Text(sampleModel.num.toString()),
FlatButton(
// 4.ボタン押下時に数値をインクリメント
onPressed: () => context.read(sampleProvider).addNum(),
child: const Text('ADD'),
),
],
),
);
},
),
),
);
}
}
処理の流れ
1. 状態管理クラスでChangeNotifierを継承
2. 画面から状態管理クラスへのアクセス用のproviderを定義
3. 画面からProviderを利用して状態管理クラスを取得(useProviderを利用)
4. 画面からProvider経由で状態を更新(context.readを利用)
5. 変更の通知して画面を更新
状態の破棄方法
Providerの定義時に".autoDispose"を付与するだけで、利用元の画面がツリーから破棄された際に状態管理クラスのインスタンスも破棄されます。
※Widgetの破棄時では無いため、例えばサンプル画面からGet.offAllAndXX等でWidgetツリーをクリア後にサンプル画面を表示しようとすると状態管理クラスが破棄されない事があります。
まとめ
1. ChangeNotifierで状態管理
2. 画面からChangeNotifierProviderを利用して状態へアクセス
3. 状態を更新したらnotifyListeners()で画面へ通知
4. autoDisposeをChangeNotifierProviderに付与しておけば状態の破棄は大体勝手にしてくれる