✨
【Flutter】popで戻ってきた時に検知して処理するWidget
はじめに
よく遷移先でデータを編集して、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
「Flutter SSOT」といったキーワードでいろいろと記事を読んでいただくことをオススメします。
ありがとうございます!
今まで社内のテックリードの方がつくったアーキテクチャを真似してMVVMで作ってるだけだったので、勉強になります。
似たようなことを私の現場では、RouteAwareでやってますね。
それをhooks化して, View内では該当コードを5~10行で済むようにしています。
これですね!!
これ便利でしたよ。
hooks使ってない現場でしたらごめんなさい...🙇♂️
ありがとうございます!
hooksは触ったことないのですが、使っているPJはネットでよく見るので今度hooks調べてみます!