Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling setState() during build without user interaction

What I did :

  • I have integrated FCM (Firebase Cloud Messaging) in my flutter app.
  • I shared the context and the setState() of each page in static variables with these two lines getting called in all the build functions of my pages :
@override
Widget build(BuildContext context) {
    StaticClass.currentContext = context;
    StaticClass.currentSetState = this.setState;
    return ... ;
}
  • I created a callback to handle the coming notifications when the app is running
fcm.configure( onMessage: (){
    StaticClass.currentSetState((){
        Navigator.pushNamed(StaticClass.currentContext, "/notifications");
  });
});

What happened :

  • I got this error:
 ══╡ 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.
...

Explanations :

  • I can't update the page (by using context or calling setState()) when the framework is building
  • This problem doesn't happen when this function is called with a user interaction

What I want :

  • Is there a way to repair my code or am I doing something wrong ?

OR

  • Is there any other solution to go to another Page when onMessage() is triggered ?

OR

  • Is there a way to know when the build function completes, to setState() without any problem ?

Please Help I'm stuck here

like image 715
Khalil Bz Avatar asked Feb 23 '19 21:02

Khalil Bz


People also ask

Can I call setState in initState?

Because we can't call setState() directly in the initState method, we can't call it from a function called by initState either. Unless this function is asynchronous and the setState call is made after the first await.

What is the main purpose of setState () method call?

Calling setState notifies the framework that the internal state of this object has changed in a way that might impact the user interface in this subtree, which causes the framework to schedule a build for this State object.

Why do you need to call setState (() }) in a StatefulWidget?

setState is a way to dynamically change the UI. We call it inside the State Object class of the StatefulWidget. Calling setState marks the corresponding Widget dirty .


1 Answers

You can call setState after rendering is done by adding a post frame callback with addPostFrameCallback method. This will be called only once and after build process is done.

WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));
like image 91
Miguel Ruivo Avatar answered Sep 23 '22 14:09

Miguel Ruivo