0
0

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 ModalBottomSheetを閉じたときに実行した処理ではriverpodの状態が更新されていなかった

Posted at

はじめに

👆のModalBottomSheetを閉じた時に特定の処理を実行する方法として、例えば以下のようなやり方があります。

            showModalBottomSheet(
              context: context,
              isScrollControlled: true,
              shape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
              ),
              builder: (context) => const BottomSheet(),
            ).whenComplete(() {
               print('ModalBottomSheetが閉じた');
            });

whenCompleteが実行されるときに取得できるriverpodで状態管理してる値が更新されず、次の操作でwhenCompleteが実行された際に反映されるという問題に直面したのです。。。

イメージとしては
①ModalBottomSheetを開いて、その中でriverpodで状態管理してる値Aを変更する
👇
②ModalBottomSheetを閉じる
👇
whenCompleteが実行される
👇
④値Aを使って必要なメソッドを実行(しかし値Aは①で変更した値ではなく、その前の値)

よくわからないかもですが、こんな感じですw

ファイルの構成はMVVMっぽい感じで以下の通り
・search_page.dart(view)
・search.dart(model)
・search_view_model.dart(ViewModel)

環境

hooks_riverpod + freezed + StateNotifierで状態管理をやってます

environment:
  sdk: ">=2.16.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  hooks_riverpod: ^2.0.0-dev.0
  freezed_annotation: ^1.1.0

dev_dependencies:
  freezed: ^1.1.1

状態が更新されていなかった時のコード

まずは思った通りの挙動にならなかった時:poop:

モデルファイル

search.dart
@freezed
class Search with _$Search {
  factory Search({
    @Default('') String date,
  }) = _Search;
}

viewファイル

search_page.dart
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import '../search_provider.dart';

class SearchPage extends HookConsumerWidget {
  const AreaAndCategory({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final search = ref.watch(SearchProvider);
    final date = searchJob.date;

     return Row(
      children: [
        Expanded(
            child: GestureDetector(
          onTap: () {
            showModalBottomSheet(
              context: context,
              isScrollControlled: true,
              shape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
              ),
              builder: (context) => const AreaSheet(),
            ).whenComplete(() {
              // ref.watchによって監視されているdateがModalBottomSheetで選択した値によって変わる・・・と思っていた。。
              ref
                  .read(SearchProvider.notifier)
                  .getItems(context: context, date: date);
            });

 }
}

処理を実行するViewModelファイル

ここの引数で受け取るdateがModalBottomSheetで変更した値ではなかった。。。

search_view_model.dart
  Future<void> getItems({
    required BuildContext context,
    String date,
  }) async {
    // 何らかの処理
    print(date);
  }

状態が更新されていた時のコード

これで思った通りの挙動になりました!!:innocent:

モデルファイル

ここは変化なし

search.dart
@freezed
class Search with _$Search {
  factory Search({
    @Default('') String date,
  }) = _Search;
}

viewファイル

getItemsメソッドに引数でdateを渡すのをやめました!!
:dancer_tone5:

search_page.dart
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import '../search_provider.dart';

class SearchPage extends HookConsumerWidget {
  const AreaAndCategory({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {

     return Row(
      children: [
        Expanded(
            child: GestureDetector(
          onTap: () {
            showModalBottomSheet(
              context: context,
              isScrollControlled: true,
              shape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
              ),
              builder: (context) => const AreaSheet(),
            ).whenComplete(() {
              // 引数をcontextだけにした
              ref
                  .read(SearchProvider.notifier)
                  .getItems(context: context);
            });

 }
}

処理を実行するViewModelファイル

viewから引数でdateを受け取るのではなく、StateNotifierのstateから取得に変更

search_view_model.dart
  Future<void> getItems({
    required BuildContext context,
  }) async {
    // 何らかの処理
    print(state.date);
  }

①ModalBottomSheetを開いて、その中でriverpodで状態管理してる値Aを変更する
👇
②ModalBottomSheetを閉じる
👇
whenCompleteが実行される
👇
④値Aを使って必要なメソッドを実行(値Aは①で変更した値)

これで上記のような思った挙動になりました!!!

誰か原因を言語化してください:raised_hands_tone2:

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?