GoRouter报错默认路由为参数化路由,但实际未使用参数化路由的问题求助
嘿,我刚看完你的问题和代码,马上就发现问题出在哪了!
你收到的错误提示说“StatefulShellBranch的默认位置不能是参数化路由”,不是因为你设置的initialLocation: '/recipe'有问题,而是你的第二个StatefulShellBranch的默认路由是参数化的!
仔细看你的代码,第二个分支里只有一个路由:/recipe/:recipe,这个路由带了路径参数:recipe,而GoRouter对每个StatefulShellBranch都有硬性要求——它的默认路由(也就是分支里的第一个/唯一路由)必须是无参数的。因为每个分支对应一个独立的导航栈(比如底部导航栏的某个标签页),它需要一个明确的、不需要额外参数就能访问的入口页面,这样切换到这个分支时,GoRouter才知道该加载哪个页面。
那怎么解决呢?给你两个可行的方案,看你的实际需求选:
方案一:把详情页作为列表页的子路由(推荐)
食谱详情页本来就应该是列表页的下级页面,属于同一个导航栈,所以你完全不需要给它单独开一个StatefulShellBranch。把参数化路由移到第一个分支的routes里当子路由就行,修改后的代码是这样的:
final router = GoRouter( initialLocation: '/recipe', routes: <RouteBase>[ StatefulShellRoute.indexedStack( builder: (context, state, navigationShell) { return MainScreen(navigationShell); }, branches: [ StatefulShellBranch( routes: [ GoRoute( path: '/recipe', builder: (context, state) => RecipeListView(), // 把详情页作为列表页的子路由嵌套进去 routes: [ GoRoute( path: ':recipe', builder: (context, state) => RecipeView(), ), ], ), ], ), // 第二个分支换成你实际需要的其他独立标签页,比如收藏页、设置页,默认路由必须无参数 StatefulShellBranch( routes: [ GoRoute( path: '/favorites', builder: (context, state) => FavoritesView(), // 替换成你的实际页面组件 ), ], ), ], ), ], );
这样既符合正常的导航逻辑,又完美满足了GoRouter对StatefulShellBranch的要求,不会再触发那个断言错误了。
方案二:给第二个分支添加无参数的默认路由(不推荐,除非有特殊业务需求)
如果你确实需要用单独的分支来放详情页(虽然从导航逻辑来说不太合理,因为详情页依赖列表页传递的参数,单独分支的默认进入状态会很尴尬),那你必须给这个分支加一个无参数的默认路由,比如:
final router = GoRouter( initialLocation: '/recipe', routes: <RouteBase>[ StatefulShellRoute.indexedStack( builder: (context, state, navigationShell) { return MainScreen(navigationShell); }, branches: [ StatefulShellBranch( routes: [ GoRoute( path: '/recipe', builder: (context, state) => RecipeListView(), ), ], ), StatefulShellBranch( routes: [ // 给这个分支新增无参数的默认路由 GoRoute( path: '/recipe-placeholder', builder: (context, state) { // 这里可以做默认处理,比如自动跳转到列表页,或者显示一个提示页面 return RecipeListView(); }, routes: [ GoRoute( path: ':recipe', builder: (context, state) => RecipeView(), ), ], ), ], ), ], ), ], );
不过这种方式下,当你切换到第二个分支时,默认会进入/recipe-placeholder这个页面,逻辑上不太顺畅,所以还是优先推荐方案一。
内容来源于stack exchange

