【Flutter】popで戻ってきた時に検知して処理するWidget

に公開5

はじめに

よく遷移先でデータを編集して、popして戻ってきた時にそのデータ更新を反映して画面更新かけたいってことあるじゃないですか。
push処理をawaitして、thenで処理いれることでそれできると思うんですけど、全部の画面遷移にそれ入れるの大変だよなーってことで、ChatGPTに聞いてみたらWidgetとして画面表示したときに検知して処理をすることができるWidgetを作ってもらえました。

Widgetのコード

class ShellPopAwareWidget extends StatefulWidget {
  final VoidCallback onPopNext;

  const ShellPopAwareWidget({required this.onPopNext, super.key});

  
  _ShellPopAwareWidgetState createState() => _ShellPopAwareWidgetState();
}

class _ShellPopAwareWidgetState extends State<ShellPopAwareWidget>
    with RouteAware {
  
  void didChangeDependencies() {
    super.didChangeDependencies();
    shellRouteObserver.subscribe(this, ModalRoute.of(context)!);
  }

  
  void dispose() {
    shellRouteObserver.unsubscribe(this);
    super.dispose();
  }

  
  void didPopNext() {
    widget.onPopNext();
  }

  
  Widget build(BuildContext context) => const SizedBox.shrink(); // UIには出さない
}

GoRouterに入れるコード

final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
final mainRouteObserver = RouteObserver<ModalRoute<void>>();
final shellRouteObserver = RouteObserver<ModalRoute<void>>();

final router = GoRouter(
  navigatorKey: navigatorKey,
  observers: [mainRouteObserver],
  initialLocation: AppRoutes.splash.path,
  routes: [
    GoRoute(
      /// 検知範囲外の画面
    ),
    ShellRoute(
      observers: [shellRouteObserver],
        /// 検知を使用したい画面はここから下に書く
以下略 ......

使い方

StatelessWidget + Consumer内でこれをWIdgetとして埋め込むと検知時に処理が走ります。
StatefulWidgetでも使えるのかな?

ShellPopAwareWidget(
    onPopNext: () {
      // 検知時の処理
    },
),

追記

これだとAPI叩き直すことになると思うので、APIの通信量気にするなら、更新したデータをモデルごとpushのthenで受け取るとかのほうがいいんですかねぇ???
それともMVVMの場合は一旦ViewとViewModelを一対一でもってる原則崩して、表示データは一貫してどこかのproviderで持っておくとか...?
なにがベストなのか一人で考えてるとまとまらない...

Discussion

y1rowy1row

一旦ViewとViewModelを一対一でもってる原則崩して、表示データは一貫してどこかのproviderで持っておくとか...?

「Flutter SSOT」といったキーワードでいろいろと記事を読んでいただくことをオススメします。

しずみやしずみや

ありがとうございます!
今まで社内のテックリードの方がつくったアーキテクチャを真似してMVVMで作ってるだけだったので、勉強になります。

FBFB

似たようなことを私の現場では、RouteAwareでやってますね。
それをhooks化して, View内では該当コードを5~10行で済むようにしています。

しずみやしずみや

ありがとうございます!
hooksは触ったことないのですが、使っているPJはネットでよく見るので今度hooks調べてみます!