在构建过程中无需用户交互就调用setState()

Kha*_* Bz 1 setstate dart firebase flutter

我做了什么 :

  • 我在flutter应用程序中集成了FCM(Firebase云消息传递)。
  • 我在静态变量中共享了每个页面的context和,setState()在页面的所有构建函数中调用了这两行:
@override
Widget build(BuildContext context) {
    StaticClass.currentContext = context;
    StaticClass.currentSetState = this.setState;
    return ... ;
}
Run Code Online (Sandbox Code Playgroud)
  • 我创建了一个回调来处理应用程序运行时即将到来的通知
fcm.configure( onMessage: (){
    StaticClass.currentSetState((){
        Navigator.pushNamed(StaticClass.currentContext, "/notifications");
  });
});
Run Code Online (Sandbox Code Playgroud)

发生了什么 :

  • 我收到此错误:
 ??? 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.
...
Run Code Online (Sandbox Code Playgroud)

说明:

  • 构建框架时,无法更新页面(通过使用上下文或调用setState())
  • 通过用户交互调用此函数时不会发生此问题

我想要的是 :

  • 有没有办法修复我的代码,或者我做错了什么?

要么

  • 触发onMessage()时,还有其他解决方案可转到另一个Page吗?

要么

  • 有没有办法知道构建函数何时完成,setState()没有任何问题?

请帮助我被困在这里

Mig*_*ivo 5

您可以setState在渲染完成后调用,方法是使用addPostFrameCallback方法添加后框架回调。构建过程完成后,将仅调用一次

WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));
Run Code Online (Sandbox Code Playgroud)

  • 您_可以_在多个地方调用此方法,例如“initState()”、“onTap()”回调等。您_不能_在“build()”方法上调用它,因为它将递归地安排重建。 (6认同)
  • 当在调试模式下看到时,这将多次触发连续构建小部件。最终减慢应用程序速度并使应用程序崩溃。 (5认同)
  • 不,不会。这实际上是重建小部件后调度新框架的正确方法。如果您遇到这种情况,那可能是因为您在错误的位置进行了调度,它将递归地调度新帧(例如,在“build”方法中)。此_应该_仅用在不依赖于小部件重建的地方,例如回调方法、状态方法等。 (2认同)