在没有用户交互的情况下在构建期间调用 setState()
Calling setState() during build without user interaction
我做了什么:
- 我在我的 flutter 应用程序中集成了 FCM(Firebase 云消息传递)。
- 我在静态变量中共享了每个页面的
context
和 setState()
,并在我页面的所有构建函数中调用了这两行:
@override
Widget build(BuildContext context) {
StaticClass.currentContext = context;
StaticClass.currentSetState = this.setState;
return ... ;
}
- 当应用 运行
时,我创建了一个回调来处理即将到来的通知
fcm.configure( onMessage: (){
StaticClass.currentSetState((){
Navigator.pushNamed(StaticClass.currentContext, "/notifications");
});
});
发生了什么:
- 我收到这个错误:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══
...
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.
...
解释:
- 我无法在构建框架时更新页面(通过使用上下文或调用 setState())
- 通过用户交互调用此函数时不会发生此问题
我想要的:
- 有没有办法修复我的代码,还是我做错了什么?
或
- 在onMessage()被触发时,是否有其他解决方案可以转到另一个页面?
或
- 有没有办法知道构建函数何时完成,setState() 没有任何问题?
请帮助我卡在这里
您可以在渲染完成后调用 setState
,方法是使用 addPostFrameCallback 方法添加 post 帧回调。这只会被调用一次并且在构建过程完成之后。
WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));
我做了什么:
- 我在我的 flutter 应用程序中集成了 FCM(Firebase 云消息传递)。
- 我在静态变量中共享了每个页面的
context
和setState()
,并在我页面的所有构建函数中调用了这两行:
@override Widget build(BuildContext context) { StaticClass.currentContext = context; StaticClass.currentSetState = this.setState; return ... ; }
- 当应用 运行 时,我创建了一个回调来处理即将到来的通知
fcm.configure( onMessage: (){ StaticClass.currentSetState((){ Navigator.pushNamed(StaticClass.currentContext, "/notifications"); }); });
发生了什么:
- 我收到这个错误:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══ ... 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. ...
解释:
- 我无法在构建框架时更新页面(通过使用上下文或调用 setState())
- 通过用户交互调用此函数时不会发生此问题
我想要的:
- 有没有办法修复我的代码,还是我做错了什么?
或
- 在onMessage()被触发时,是否有其他解决方案可以转到另一个页面?
或
- 有没有办法知道构建函数何时完成,setState() 没有任何问题?
请帮助我卡在这里
您可以在渲染完成后调用 setState
,方法是使用 addPostFrameCallback 方法添加 post 帧回调。这只会被调用一次并且在构建过程完成之后。
WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));