Skip to content

GoRouterで複数のパラメータを渡す方法

go_routerを使用する際、複雑なデータを次の画面に渡す必要がある場合があります。従来のFlutterナビゲーションでは簡単だったこのプロセスが、go_routerでは少し異なるアプローチが必要です。本記事では、go_routerで複数のパラメータを効果的に渡す方法を解説します。

問題点:従来のナビゲーションとgo_routerの違い

従来のFlutterナビゲーションでは、複数のパラメータを簡単に渡すことができました:

dart
Navigator.of(context).push(MaterialPageRoute(
  builder: (_) => CatalogFilterPage(
    list: list,
    bloc: bloc,
  )
));

しかし、go_routerではこの方法が使えず、代わりに以下の方法を検討する必要があります。

解決策:3つの主要なアプローチ

go_routerでは、主に以下の3つの方法でパラメータを渡すことができます:

1. pathParametersを使用する方法

パラメータの数が事前にわかっている場合に適しています。パス内でパラメータを明示的に定義します。

ルートの定義:

dart
GoRoute(
  path: '/sample/:id1/:id2',  // パス内でパラメータを定義
  name: 'sample',
  builder: (context, state) => SampleWidget(
    id1: state.pathParameters['id1'],
    id2: state.pathParameters['id2'],
  ),
),

ナビゲーションの呼び出し:

dart
ElevatedButton(
  onPressed: () {
    var param1 = "param1";
    var param2 = "param2";
    context.goNamed("sample", pathParameters: {
      'id1': param1, 
      'id2': param2
    });
  },
  child: const Text("移動"),
),

WARNING

Go Routerのバージョンに注意してください:

  • バージョン7未満:paramsを使用
  • バージョン7〜10:pathParametersを使用
  • バージョン10以上:pathParametersuri.queryParametersを使用

2. queryParametersを使用する方法

パラメータの数が不定な場合や、柔軟性が必要な場合に適しています。

ルートの定義:

dart
GoRoute(
  name: "sample",
  path: "/sample",          
  builder: (context, state) => SampleWidget(
    id1: state.uri.queryParameters['id1'],
    id2: state.uri.queryParameters['id2'],
  ),
)

ナビゲーションの呼び出し:

dart
ElevatedButton(
  onPressed: () {
    var param1 = "param1";
    var param2 = "param2";
    context.goNamed("sample", queryParameters: {
      'id1': param1, 
      'id2': param2
    });
    // または直接URL形式で
    // context.go("/sample?id1=$param1&id2=$param2");
  },
  child: const Text("移動"),
),

3. extraを使用する方法(オブジェクトを渡す場合)

複雑なオブジェクトやモデルを渡す場合に最適な方法です。

ルートの定義:

dart
GoRoute(
  path: '/item-screen',
  builder: (context, state) {
    MenuModels models = state.extra as MenuModels;
    return ItemScreen(menuModels: models);
  },
),

ナビゲーションの呼び出し:

dart
context.push('/item-screen', extra: widget.menuModels);

複数のオブジェクトを渡す必要がある場合は、Mapを使用します:

dart
GoRoute(
  path: '/path',
  name: 'path-name',
  builder: (context, state) {
    Map<String, dynamic> extra = state.extra as Map<String, dynamic>;
    return ScreenName(
      par1: extra['par1'],
      par2: extra['par2'],
    );
  },
),
dart
context.goNamed(
  'path-name',
  extra: {
    'par1': object1,
    'par2': object2,
  },
),

ベストプラクティスと推奨事項

  1. シンプルなデータの場合pathParametersまたはqueryParametersを使用
  2. 複雑なオブジェクトの場合extraを使用
  3. 型安全性:常に適切な型キャストを行う
  4. null安全性:null許容型を使用し、適切なエラーハンドリングを実装

TIP

extraを使用する場合は、渡されるオブジェクトがシリアライズ可能である必要はありませんが、アプリの状態管理と整合性を考慮することが重要です。

まとめ

go_routerで複数のパラメータを渡す方法は、データの種類や要件に応じて選択できます。シンプルな文字列データの場合はpathParametersqueryParametersを、複雑なオブジェクトの場合はextraを使用することが推奨されます。各方法にはメリットとデメリットがあるため、アプリケーションの要件に最適な方法を選択してください。