いざってときに役に立つFlutterプロジェクトテンプレートを作りたい
参考資料
ここまでガチガチじゃなくていいけど、こう…ね?
MVVMでグローバルステートをStateNotifierでいい感じに扱いたい
Provierじゃちょっときつい(できなくはない)けどRiverpodならいい感じになりそう
前にRiverpodはMVVMに向いてない的なこと言ったけど、それはViewModelとして不適切じゃないかという趣旨
色々考えたけど、グローバルステート(≒あらゆるデータソースのキャッシュ)を扱う&いい感じのDIコンテナとして振る舞ってくれる利点のほうが上回る
本当に気になるならScopedにすればええ
↑を踏まえて、
ただのTODOリストとかじゃないやつ
いざってときに参考にならない
ローカルデータソース、リモートデータソースがちゃんとあるやつ
とかそういうの作っときたい
順番
1. 普通にChangeNotifier(ViewModel), StateNotifierでそれっぽいのをつくる
2. Navigator 2.0 を導入する
3. ネットワーク経由でなにかやる
メモ
命名はMVVMベース
Modelと同じ層にビジネスロジックを持つ想定
一つのクラスにまとめるなどの思想にとらわれず、Dartらしい・Riverpodらしい書き方を活用したい
Model
models/
app_state/
app_state.dart
app_state.freezed.dart
controllers/
xx_state/
ディレクトリ構成ちょっと見直したほうがいいかもしれん
controllersが微妙?
controllers is 何
code: app_state_controller.dart
final appStateControllerProvider =
StateNotifierProvider((_) => AppStateController());
class AppStateController extends StateNotifier<AppState> {
AppStateController() : super(AppState());
Future setAppTitle(String value) async {
// NOTE: Perform pseudo async action.
await Future.delayed(const Duration(seconds: 1));
state = state.copyWith(title: value);
}
}
要は StateNotifier
ViewModel
code: view_model.dart
abstract class ViewModel with ViewModelMixin {}
mixin ViewModelMixin {
@protected
ProviderReference get ref;
BuildContext get buildContext =>
ref.read(navigatorKeyProvider).currentState!.overlay!.context;
}
とりあえず BuildContext を取れる実装
Model層から値をwatchするときは、Providerのcreate関数内でwatchする。
現状、Widgetではflutter_hooks を使わないと任意のProviderからselectすることができない。
またWidget以外では全く方法が用意されていない。
select相当のことをするには、別のProviderを用意することになる。
code:dart
final _memosState =
Provider((ref) => ref.watch(memoStateControllerProvider.state).memos);
final homeViewModel = Provider.autoDispose((ref) {
final memos = ref.watch(_memosState);
return HomeViewModel(ref, memos);
});
これも参照するModelが増えたときにどう最適化するかが課題となってくる。無理にViewModelで受ける必要もない?
ChangeNotifierにするかどうか問題
上述したように現在Riverpodではselectができない。
ViewModelでは画面のロード状態などを管理し、適宜ChangeNotifierでViewに反映させる的なことをprovider 時代ではやっていたが、別のアプローチを考えてみる。
1. 変数一つ一つに対してprivateな StateProvider を作る
code: dart
final _isProcessingProvider = StateProvider.autoDispose((_) => false);
2. Viewに関する状態変数をまとめたクラスを持つ StateNotifier にする