Zenn

【Flutter】 go_routerのGoRouteとGoRouteData

2025/03/15に公開

go_routerに関して

実務でgo_routerを触っていて、ふと様々な記載方法があると思いました。
記事でよくみる記載方法と実務では異なり、疑問に思ったので詳しく調べてみた。
気になる部分をただただ書いていく。

https://pub.dev/packages/go_router

go_routerの書き方

よく記事でみるgo_routerの書き方 (記事に記載ある部分をざっくり引用させて頂きます)
https://zenn.dev/channel/articles/af4ffd813b1424

GoRouteを直接使う方法

///////////////////////////////
/// router.dart ///////////////
// 変数に入れる
final goRouter = GoRouter(
  // アプリが起動した時
  initialLocation: '/',
  // パスと画面の組み合わせ
  routes: [
    GoRoute(
      path: '/',
      name: 'initial',
      pageBuilder: (context, state) {
        return MaterialPage(
          key: state.pageKey,
          child: const MyHomePage(),
        );
      },
    ),
  /// 他画面
  GoRoute(
  /// 以下省略
    ),
  ],
);
///////////////////////////////
///// main.dart ///////////////
 return MaterialApp.router(
      title: 'hogeアプリ',
      routerConfig: goRouter,
  /// 以下略
   )

検索してよく見るパターンが上記ですね。

僕は上記書いたことないのでなんとも言えないのですが、シンプルな定義ができるのかなと。
ただ少数ならいいんですが、多くなるとミスりそうなイメージです。

また、値を受け渡すときに型チェックがないので僕としては不安材料かなと。。。

context.push('/hoge_hoge', extra: "Hello"); // extra は String だけど、何でも入れられる

GoRouteDataを使う方法(型安全なルート管理)

自分が書いていたのが下記。main.dartでの書き方は一緒。

///////////////////////////////
/// router.dart ///////////////

final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>();

final router = GoRouter(
  routes: $appRoutes,
  initialLocation: hogehogeRoute.path,
  navigatorKey: rootNavigatorKey,
);

/// ここが重要
<HogehogeRoute>(
  path: '/hoge_hoge',
)

class HogehogeRoute extends GoRouteData {
  /// Constructor
  const HogehogeRoute();

  
  Widget build(BuildContext context, GoRouterState state) =>
      HogehogePage();
}

上記の記載方法ではコマンドによる build が必要

flutter pub run build_runner build --delete-conflicting-outputs

使い方は下記。

HogehogeRoute().push(context);

pushの他に、goやpushReplacementの書き方もあります。

rootNavigatorKey

rootNavigatorKeyはGoRouterのルート(最上位の Navigator)を適切に管理するために必要です。
戻る時とかにどこに戻ったらいいのか分からなくならない様に、元のrootNavigatorKeyを宣言しておくイメージです。

@TypedGoRoute

@TypedGoRouteは「ルート定義をGoRouterに自動的に追加する」ためのアノテーション(TypedGoRoute) です。

flutter pub run build_runner build --delete-conflicting-outputs

上記のコマンドを使えば自動的にrouterに登録されて遷移出来る様になります。

routes: $appRoutes,

登録先は、上記の先に登録されてます。

あとは同じ様に画面遷移先が出来るたびに作成するのですが、上記の様な下記方はまれです。
一番使われている下記方はこちらの様なイメージ。タブで使われているイメージがおおいですね。
特にボトムタブ。

https://zenn.dev/koichi_51/articles/fd0c6ebe7037a2

豆知識ですが、上記のリンク先に書いてある TypedStatefulShellRoute の中に記載せず、独立して下記の様に書くことが出来るし、遷移もできます。

<jijiRoute>(
  path: jijiRoute.path,
  routes: [
    TypedGoRoute<guguRoute>(
      path: guguRoute.path,
    ),
  ],
)

ただ、例えば独立したjijiRouteに遷移して、TypedStatefulShellRouteの中に記載あるhogehogeRuteの画面に遷移しようとするとエラーになります。

実際に試してエラーになりました。。。
定義していないルートに遷移したために起きるエラーみたいです。

遷移のカスタム

GorouteDataで画面遷移の方法もかえれました。

https://zenn.dev/rionishino/articles/2e33ae1d950e6a

GoRouteで直接書く方が記事が多かったので自分の記事で備忘録でかきこ。

結局どっちを使うべき?

比較項目 GoRouteDataを使う方法 GoRouteを直接使う方法
型安全 ×
コードの見やすさ ×
アニメーション ×
拡張性

コードの見やすさに関してはどちらも見やすいかな。。と思いましたが、GorouteDataの方は関数の様に書けるのがいいかなと。

個人の感想での上記格付け?なのであまり気にせず。

ただ、GorouteDataの方が実務では安心して書けると思います!型安全なので!

以上!!!

Discussion

ログインするとコメントできます