whitebear
whitebear

Reputation: 12423

setState() or markNeedsBuild() called during build error

I am making BackBtn class which is used at many places in this application.

Designs are the same and only the behavier when it pressed is different.

So, I want to pass the function in constructor, which is used when the button pressed.

However it shows the error below

flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown building BackBtn(dirty):
flutter: setState() or markNeedsBuild() called during build.
flutter: This Overlay widget cannot be marked as needing to build because the framework is already in the
flutter: process of building widgets.  A widget can be marked as needing to be built during the build phase
flutter: only if one of its ancestors is currently building. This exception is allowed because the framework
flutter: builds parent widgets before children, which means a dirty descendant will always be built.
flutter: Otherwise, the framework might not visit this widget during this build phase.
flutter: The widget on which setState() or markNeedsBuild() was called was:
flutter:   Overlay-[LabeledGlobalKey<OverlayState>#320d3]
flutter: The widget which was currently being built when the offending call was made was:
flutter:   BackBtn

These are the code that I made.

class BackBtn extends StatelessWidget{

  final Function onPressed;  
  const BackBtn({ Key key ,this.onPressed}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment(1.0,-1.0), 
      child: FlatButton(
        onPressed: onPressed(),      
        padding: EdgeInsets.all(50),
        child:  Image.asset('images/BackIcon.png')
      )
    );
  }
}

BackBtn(
    onPressed: () => Navigator.push(context,MaterialPageRoute(
    builder: (context) => MyHomePage())),
),

Upvotes: 2

Views: 4244

Answers (1)

Robin Reiter
Robin Reiter

Reputation: 2517

You are executing the onPressed() callback already upon assigning it to FlatButton().

Try it with removing the braces like so:

class BackBtn extends StatelessWidget{

  final Function onPressed;  
  const BackBtn({ Key key ,this.onPressed}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment(1.0,-1.0), 
      child: FlatButton(
        onPressed: onPressed, // Removed the Braces ()      
        padding: EdgeInsets.all(50),
        child:  Image.asset('images/BackIcon.png')
      )
    );
  }
}

Tldr;

When you leave the braces it will immediately execute your onPressed handler while building the widget. That means you will hit the navigator and all other stuff in the middle of a build and not only when pressing the actual button. That causes your error.

Upvotes: 6

Related Questions