我遇到了一个问题,当我尝试通过 Navigator.pop(context) 或 Navigator.of(context).pop “返回”时,前一页尝试在 GoRouter 中重建,导致错误,因为我没有传入所需的参数。我认为颤振导航保留了前几页的构建/状态……没有这一点就打败了导航堆栈的整个要点。
即,考虑此路由设置,用户将应用程序打开到 LandingPage(),然后单击一个按钮,该按钮使用“necessaryParam”导航到 InnerPage()。然后,他们从 InnerPage 路由到 InnerPage2(),在此处单击“后退”按钮,该按钮会触发 Navigator.pop(context) 的效果。这会将用户路由回 InnerPage(),但会引发异常,因为未传递“necessaryParam”。
为什么要重建而不是从导航堆栈中弹出 InnerPage2() ?导航堆栈只是在 pop() 上重建的一堆路线吗?不过,我记得它保存了状态,所以这似乎不对。任何见解将不胜感激。
我意识到一个解决方案是使用 context.goNamed("inner", extra: paramObject) 而不是 Navigator.pop(context) 强力重新传递来自 InnerPage2 的参数,但如果维护导航堆栈,这将是一个这是一种非常笨拙且低效的方法,因为导航堆栈只会无限期地继续增长,这似乎非常错误。
routes: <RouteBase>[
GoRoute(
path: '/landing',
builder: (BuildContext context, GoRouterState state) =>
LandingPage(),
routes: <RouteBase>[
GoRoute(
path: 'inner',
name: 'inner',
builder: (BuildContext context, GoRouterState state){
// extract params from state.extra
ParamObject? params = state.extra != null ? state.extra as ParamObject : null;
var necessaryParam = params?.variable
if(necessaryParam != null)
{
return InnerPage(param: necessaryParam);
}
else{
throw Exception("necessaryParam missing!");
},
routes: <RouteBase>[
GoRoute(
path: 'inner2',
name: 'inner2',
builder: (BuildContext context, GoRouterState state){
return InnerPage2();
},
),
]
),
],
),
],
编辑:我只是用一条没有任何参数的单独路径对此进行了一些探索。当路由(即)更改 InnerPage 上的状态、路由到 InnerPage2、context.pop() 且 InnerPage 的状态未重置时,状态会被保存。有趣的是,我在 InnerPage 的 GoRouter 构建器中添加了一条 print 语句,它不仅在 InnerPage2 的“返回”按下时触发,而且在从 InnerPage 路由到 InnerPage2 时也会触发。
GoRouter 似乎在 context.pop() 上重建但恢复状态,因此一个足够简单的解决方案是使参数可选并将它们存储在状态变量中,如下所示:
// inside Widget build of InnerPage(), assuming param is an optional parameter
ValueNotifier<String> necessaryParamState = useState("");
if(necessaryParam!= null){
// on initial routing, won't trigger on context.pop()
necessaryParamState.value = param
}
GoRouter 构建器应该类似于:
builder: (BuildContext context, GoRouterState state){
// extract params from state.extra
ParamObject? params = state.extra != null ? state.extra as ParamObject : null;
var? necessaryParam = params?.variable
if(necessaryParam != null)
{
// on press from previous page, pass relevant parameters for state init
return InnerPage(
param: necessaryParam
);
}
else{
// on "back" press from InnerPage2, parameters are loaded from state
return InnerPage();
}
},
Ofc 这并不完美,但看起来它可以工作。如果有人知道的话,很想看到一个更干净的解决方案。