6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Flutter : MVVMでriverpodを使った画面表示時の書き方

Posted at

やりたいこと

画面表示時にAPIを介して値を取得し、画面表示したい。
refを使って他のプロバイダのstateを変更したい。 ⇦ これが厄介だった

問題

・ConsumerWidgetにはiOSの様にviewDidLoadなどの細かいlifecycleが提供されていない
・viewModelProviderを生成する時に下記のエラーが出る(プロバイダーの生成中に他のプロバイダーの値は変えちゃダメだよ的なやつ)
Providers are not allowed to modify other providers during their initialization.

簡単な方法

  1. viewModelの生成時にコンストラクタで値取得を行う
    → refを通して他のプロバイダーのstateを変更しようとするとcrashする。(変更しないのであれば問題ない)
  2. FutureProviderを使う
    → loadingやerrorなどの処理を個別に書いたりしないといけないので少し面倒。今回のMVVMに合わせて実装をするのが難しくなる
  3. Consumerを重ねる → これを解説します

コード

HogePage
class HogePage extends ConsumerWidget {
  const HogePage({
    Key? key,
  }) : super(key:key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final provider = hogeViewModelProvider;
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      ref.read(provider.notifier).initialize();
    });
    return Consumer(
      builder: (_, widgetRef, __) {
        final state = widgetRef.watch(provider);
      }
    }
  }
}
HogeViewModel
final hogeViewModelProvider = StateNotifierProvider.autoDispose<bool>((ref) {
  return HogeViewModel(false, reader: ref.read);
});
class HogeViewModel extends StateNotifier<bool> {
  HogeViewModel(bool state, { required this.reader }) : super(state);

  final Reader reader;

  void initialize() {
     // ここに画面表示時の処理を記載する
  }
}
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?