Flutter

Solved – setState() or markNeedsBuild() called during build Error – Flutter

The error ‘setState() or markNeedsBuild() called during build Error’ is one of the most common error that occurs in Flutter Application Development. In this post we will see how to get rid of this error.

Reasons of setState() or markNeedsBuild() called during build Error

Before understanding the reason behind this, we need to understand the lifecycle of a widget. Because this error belongs to the lifecycle of widgets.

Lifecycle of Widgets in Flutter

The lifecycle of a stateful widget goes like this:

Understanding this lifecycle is crucial for managing state, as initState() provides an opportunity to set up initial values and perform actions before the widget is rendered for the first time.

The error message “setState() or markNeedsBuild() called during build” typically occurs in Flutter when you try to call setState() or markNeedsBuild() within the build() method of a widget or while the widget tree is being constructed. This is not allowed because it can cause an infinite loop or unexpected behavior.

Reason 1

This error occurs when you try to show a dialog before the completion of Widget build.

  showDialog(
    context: context,
    builder: (BuildContext context) {
        return AlertDialog(
          title: Text("Alert"),
        );
  }); //Error: setState() or markNeedsBuild() called during build.

  return Scaffold(
        body: Center(
          child: Text("Hello World")      
        )
  );
}

Output

setState() or markNeedsBuild() called during build Error

Reasons 2

When you call function of view model in initState() method of stateful widget, and that function calls notifyListener() function.

@override
void initState() { 
  Provider.of<ItemsViewModel>(context,listen: false).fetchItems();
}

 Solutions

You can solve this error by two methods.

Solution 1: addPostFrameCallback

To solve the “setState() or markNeedsBuild() called during build” error in Flutter, ensure that you’re not calling setState() or markNeedsBuild() directly within the build() method of your widget. Instead, use them in response to user actions, asynchronous events, or in lifecycle methods like initState() or callbacks.

If you want to show a SnackBar of a dialog in before the completion of widget then you have to put your code in addPostFrameCallback().

WidgetsBinding.instance.addPostFrameCallback((_) {
showDialog(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        title: Text("Alert?"),
      );
    }); //Error: setState() or markNeedsBuild() called during build.
});

addPostFrameCallback() is a method of the WidgetsBinding class. This method schedules a callback to be called after the current frame has been painted in the widget tree. Essentially, it allows us to perform certain actions or execute code after the current frame has finished rendering on the screen.

Solution 2: Future.delayed

You can also overcome this error by using Future.delayed() bunction like this.

Future.delayed(Duration.zero,(){
  showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text("Alert"),
        );
      });
});

Future.delayed is a function to schedule a task to be executed with a delay of zero duration. It might seem counterintuitive to delay something by zero seconds, but what this actually does is it schedules the function to run in the next event loop iteration. Essentially, it allows you to defer executing a piece of code until the current execution stack is cleared, giving priority to other pending tasks in the event loop.

You can also read how to zoom image in flutter

Leave a Reply

Your email address will not be published. Required fields are marked *