🛴

go_routerやって躓いたところ!

2022/08/20に公開

最近流行りのライブラリを使ってみたが...

go_routerなるものが、流行っていてやってみましたが、ルーティングを追加するだけなのに、ページが見つからないエラー画面が出てきた?

今回使用したライブラリ
https://pub.dev/packages/go_router

ルーティングを追加しただけなのだが、ページが見つからないらしく、エラー画面が表示される?
こちらのコードを参考に、ルーティングの設定を追加したら、うまく行った!

final _router = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      redirect: (_) => '/family/${Families.data[0].id}',
    ),
    GoRoute(
      path: '/family/:fid',
      builder: ...,
  ],
);

Readmeのものに、設定を追加しただけのコード。最初はエラーにハマった😇
公式のドキュメントをよく読めば設定はできた😅
とはいっても破壊的な変更が多いらしいく、編集した2022年の12月22日の現在は、以前書いたこのコードでは動かないかもしれません!

/// GoRouterの画面遷移の設定
  final GoRouter _router = GoRouter(
    routes: <GoRoute>[
      GoRoute(
        path: '/',
        builder: (BuildContext context, GoRouterState state) =>
            const Page1Screen(),
        routes: <GoRoute>[
          GoRoute(
            path: 'page2',
            builder: (BuildContext context, GoRouterState state) =>
                const Page2Screen(),
          ),

          /// この下にGoRoute(),を書いてPage3へのルーティングを設定する
          GoRoute(
            path: 'page3',
            builder: (BuildContext context, GoRouterState state) =>
                const Page3Screen(),
          ),
        ],
      ),
    ],
  );
}

公式チュートリアルを参考に手を加えた、コード

main.dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_app/page_three.dart';
import 'package:go_router_app/page_two.dart';

// このシナリオでは、シンプルな2ページ構成のアプリを示します。
//
// 最初のルート '/' は Page1Screen にマップされ、2 番目のルート '/page2' は Page2Screen にマップされます。
// はPage2Screenにマップされます。ページ間を移動するには、各ページにあるボタンを押す。
// ページ間の移動は
//
// onPressコールバックは、context.go()を使用して別のページに移動する。これは
// ブラウザのURLバーに直接URLを入力するのと同じです。

void main() => runApp(App());

/// メインとなるアプリ。
class App extends StatelessWidget {
  /// アプリを作る [App].
  App({Key? key}) : super(key: key);

  /// アプリのタイトルです
  static const String title = 'GoRouter Example: Declarative Routes';

  /// ここで、ルーティングの設定を行う
  
  Widget build(BuildContext context) => MaterialApp.router(
        routeInformationProvider: _router.routeInformationProvider,
        routeInformationParser: _router.routeInformationParser,
        routerDelegate: _router.routerDelegate,
        title: title,
      );

  /// GoRouterの画面遷移の設定
  final GoRouter _router = GoRouter(
    routes: <GoRoute>[
      GoRoute(
        path: '/',
        builder: (BuildContext context, GoRouterState state) =>
            const Page1Screen(),
        routes: <GoRoute>[
          GoRoute(
            path: 'page2',
            builder: (BuildContext context, GoRouterState state) =>
                const Page2Screen(),
          ),

          /// この下にGoRoute(),を書いてPage3へのルーティングを設定する
          GoRoute(
            path: 'page3',
            builder: (BuildContext context, GoRouterState state) =>
                const Page3Screen(),
          ),
        ],
      ),
    ],
  );
}

/// 1ページ目の画面です。
class Page1Screen extends StatelessWidget {
  /// 最初のページを作る [Page1Screen].
  const Page1Screen({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
            backgroundColor: Colors.indigo, title: const Text(App.title)),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () {
                  context.go('/page2');
                  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                    content: Text('Page2へ移動しました!'),
                  ));
                  print('Page2へ移動しました!');
                },
                child: const Text('Go to page 2'),
              ),

              /// Page3へ移動するボタンを追加
              const SizedBox(height: 20),
              ElevatedButton(
                onPressed: () {
                  context.go('/page3');
                  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                    content: Text('Page3へ移動しました!'),
                  ));
                  print('Page3へ移動しました!');
                },
                child: const Text('Go to page 3'),
              ),
            ],
          ),
        ),
      );
}

page_two.dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

/// 2ページ目の画面です。
class Page2Screen extends StatelessWidget {
  /// 2ページ目を作る [Page2Screen].
  const Page2Screen({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
            backgroundColor: Colors.amber, title: const Text('Page2です!')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () {
                  Navigator.pop(context);
                  context.go('/');
                  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                    content: Text('戻るボタンが押されました!'),
                  ));
                  print('Homeへ移動しました!');
                },
                child: const Text('Homeへ戻る!!!'),
              ),
            ],
          ),
        ),
      );
}

page_three.dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

/// 3ページ目の画面です。
class Page3Screen extends StatelessWidget {
  /// 3ページ目を作る [Page3Screen].
  const Page3Screen({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
            backgroundColor: Colors.green, title: const Text('Page3です!')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () {
                  Navigator.pop(context);
                  context.go('/');
                  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                    content: Text('戻るボタンが押されました!'),
                  ));
                  print('Homeへ移動しました!');
                },
                child: const Text('Homeへ戻る!!!'),
              ),
            ],
          ),
        ),
      );
}

使ってみた感想

ルーティングの設定さえしてしまえば、onPressed() {} の中に、go.contextと短く書くだけですむ!
便利ですね。
業務では、プロが書いてるカッコイイ書き方がありますが、真似しても再現できなかったので、今はドキュメント通りの書き方で使っていこうかなと思います。
すぐに、新しいライブラリが出てくるから、覚えるの大変です🤪
Flutterがそれだけ世界で人気だということでしょうね。
スポーツで例えるならサッカーかな⚽️

Discussion