You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GoRouter子路由传递参数/额外对象的方法及类型错误排查

GoRouter子路由传参方法及Null类型错误解决

一、子路由传递参数的三种常用方式

GoRouter子路由支持多种传参方式,常用的有三种:

  • 路径参数:在路由path中定义占位符(如a/:num),通过state.params获取,适合必填的结构化参数。
  • 查询参数:导航时在URL后拼接?key=value,通过state.queryParams获取,适合可选参数。
  • extra对象:通过导航时的extra字段传递任意类型对象,但返回导航时该字段会被置为null,这也是你报错的核心原因。

二、错误原因

你从PageB导航回PageA时,没有重新传递extra参数,导致state.extra为null。但你直接将其强制转换为Map<String, dynamic>,后续取res['num']赋值给int类型的num时,null无法转换为int,触发类型错误。

三、解决方案

方案1:用路径参数传递(推荐,避免null问题)

修改路由定义,把num设为路径参数,这样参数会被编码到URL中,返回时不会丢失:

final _router = GoRouter(
  debugLogDiagnostics: true,
  initialLocation: '/',
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => TopPage(),
      routes: [
        GoRoute(
          // 定义路径参数num
          path: 'a/:num',
          builder: (context, state) {
            // 解析参数为int,处理可能的转换失败
            final num = int.tryParse(state.params['num'] ?? '');
            return PageA(
              num: num ?? 0, // 给默认值避免null
            );
          },
          routes: [
            GoRoute(
              path: 'b',
              builder: (context, state) {
                // 从父路由的params中获取numFromA
                final numFromA = int.tryParse(state.params['num'] ?? '');
                return PageB(
                  numFromA: numFromA ?? 0,
                );
              },
            ),
          ],
        ),
      ],
    ),
  ],
);

导航示例:

  • 进入PageA:context.go('/a/123')
  • 从PageB返回PageA:context.go('/a/${widget.numFromA}')

方案2:兼容extra为null的情况

如果坚持使用extra,需要在PageA的builder中增加null判断,同时返回时手动传递参数:

// 修改PageA的路由builder
GoRoute(
  path: 'a',
  builder: (context, state) {
    // 先判断extra是否为null,再转换类型
    final res = state.extra as Map<String, dynamic>?;
    return PageA(
      num: res?['num'] as int? ?? 0, // 给默认值防止null
    );
  },
  routes: [
    GoRoute(
      path: 'b',
      builder: (context, state) {
        final res = state.extra as Map<String, dynamic>?;
        return PageB(
          numFromA: res?['numFromA'] as int? ?? 0,
        );
      },
    ),
  ],
)

从PageB返回时需重新传递extra:

// PageB中的返回逻辑
context.go('/a', extra: {'num': widget.numFromA});

方案3:状态管理共享参数

如果参数需要在多个页面共享,或者结构复杂,可以用Provider、Riverpod等状态管理工具存储参数,页面直接从状态中读取,无需通过路由传递。

四、关键注意点

  • extra仅在正向导航时有效,返回导航(pop、go回上一级)不会自动携带,必须手动传递。
  • 路径/查询参数会被编码到URL,适合简单基本类型;extra可传复杂对象,但页面重建或热重启时可能丢失数据。

内容的提问来源于stack exchange,提问作者Masahiro Aoki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 04:01:56