FlutterError(在构建过程中调用了setState()或markNeedsBuild()(在将未经身份验证的用户重定向到登录页面时)
FlutterError(在构建过程中调用了setState()或markNeedsBuild()(在将未经身份验证的用户重定向到登录页面时)
如果用户未登录,则我有一个经过验证的Flutter页面,会将用户重定向到登录页面。页面的代码如下:
@override
void initState() {
super.initState();
if (!loggedIn) {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => LoginPage()),
(Route
);
}
}
但是我遇到了以下错误:
Exception has occurred.
FlutterError (setState() or markNeedsBuild() called during build.
This Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was:
Overlay-[LabeledGlobalKey
The widget which was currently being built when the offending call was made was:
_SelectionKeepAlive)
有什么方法可以根据条件将用户重定向到另一个页面?
当在构建期间调用setState()或markNeedsBuild()时,会出现FlutterError (setState() or markNeedsBuild() called during build)这个错误。出现这个错误的原因是在构建期间尝试更新widget的状态或触发重建。
在上面的代码中,如果用户未登录,则在initState()方法中使用Future.delayed()函数延迟执行跳转到登录页面的操作。即使将延迟时间设置为零,回调函数也会在widget自身初始化之后启动。
为了解决这个问题,我们可以使用Future.delayed()函数将setState()或markNeedsBuild()的调用延迟到build方法之后。这样,就可以避免在构建期间调用这些方法,从而解决了出现这个错误的问题。
下面是修改后的代码:
void initState() {
super.initState();
Future.delayed(Duration.zero).then((_) {
if (!loggedIn) {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => LoginPage()),
(Route<dynamic> route) => false,
);
}
});
}
通过将延迟时间设置为Duration.zero,我们可以确保回调函数会在build方法之后立即执行,从而避免了在构建期间调用setState()或markNeedsBuild()方法的错误。
总结起来,避免在构建期间调用setState()或markNeedsBuild()方法可以通过使用Future.delayed()函数将这些调用延迟到build方法之后来解决。
在 Flutter 中,当在构建期间调用 setState() 或 markNeedsBuild() 时会报错 "FlutterError (setState() or markNeedsBuild() called during build)"。这个问题的出现是因为在构建期间调用了这两个方法,违反了 Flutter 构建流程的规则。
解决这个问题的方法是修复路由。根据以上代码,可以使用 SchedulerBinding 来达到相同的效果。具体做法是在 initState() 方法中使用 addPostFrameCallback() 方法:
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) {
if (!loggedIn) {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => LoginPage()),
(Route
);
}
});
}
这段代码的作用是在当前帧渲染完成后执行回调函数。在回调函数中,如果用户没有登录,就使用 Navigator.pushAndRemoveUntil() 方法将路由导航到登录页面,并移除之前的所有路由。
然而,这个解决方法是不正确的。因为在构建期间调用 setState() 或 markNeedsBuild() 是不被允许的,说明这个部件在构建时应该被避免构建。正确的解决方法是修复路由,而不是绕过错误。
希望这个解答对您有所帮助。如果您需要更多关于正确实现的信息,请提供更多细节或参考相关链接。