setState() or markNeedsBuild() called during build error

浪子不回头ぞ 提交于 2021-01-04 09:26:16

问题


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())),
),

回答1:


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.



来源:https://stackoverflow.com/questions/59136054/setstate-or-markneedsbuild-called-during-build-error

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!