☺️
ChangeNotifierProviderにてログイン状態を別ウィジェットでも使用できるようにする実装方針
コードの可読性向上のためにFirebase
のログイン状態管理を別クラスに切り出す実装をした。
その際にChangeNotifierProvider
を使用したので、最小の実装を紹介する。
(反響があればfirebaseのログイン状態管理をまとめる)
やりたいこと
- ログイン状態を別クラスのインスタンスで管理して、別ウィジェットからアクセスできるようにしたい
- 状態管理をウィジェットから独立させて、コードをわかりやすくしたい
ChangeNotifierProvider
実装例
カウンターアプリでの以下の3ステップ
- 状態管理したい対象を準備
- 状態管理を使用したいウィジェットを定義
- 状態管理された対象を利用する
状態管理したい対象を準備
Counter
クラスは ChangeNotifier
を継承しており、状態を管理するためのメソッド (increment
) と状態の変更を通知するための notifyListeners
メソッドを提供している。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Counter with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
状態管理を使用したいウィジェットを定義
main
関数で ChangeNotifierProvider
を使って、アプリ全体に Counter
クラスのインスタンスを提供しています。
Counter
クラスのインスタンスの利用範囲は実装の煩雑さを防ぐために大きすぎない方がよろしい。
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Counter(),
child: MyApp(),
),
);
}
状態管理された対象を利用する
context.watch<Counter>()
を使って、Counter
クラスの count
の値を取得し、それに応じてUIを更新します。
watch
メソッドは、プロバイダが提供する値を監視し、値が変わるとウィジェットを再ビルドする。
context.read<Counter>()
を使って、Counter
クラスのメソッドを呼び出し、状態を変更する。
read
メソッドは、状態の変更をトリガーするのに使用され、UIの再ビルドしない。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Counter App')),
body: Center(
child: Text(
'${context.watch<Counter>().count}',
style: TextStyle(fontSize: 48),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<Counter>().increment(),
child: Icon(Icons.add),
),
),
);
}
}
Discussion