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:
Constructor: The constructor of the widget is called first.
initState(): Then, the initState() method is invoked. This method is typically used for initializing variables, subscribing to streams, or performing any setup that needs to be done before the widget is fully created.
build(): Finally, the build() method is called. This is where the UI for the widget is constructed. It’s called after initState() and subsequently whenever the widget needs to rebuild due to changes in state.
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
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