I am seeing this mounted
syntax. What is it for? Could you give me sample?

- 22,623
- 19
- 99
- 186

- 2,560
- 7
- 23
- 56
2 Answers
TL;DR: A widget is mounted if it has state. If the widget is no longer mounted, i.e it has been closed or disposed, its state can no longer be updated. Therefore, we check if a widget is mounted to determine its state can still be updated.
Mounting is the process of creating the state of a StatefulWidget and attaching it to a BuildContext.
Take the following example:
class Example extends StatefulWidget {
@override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
@override
Widget build(BuildContext context) {
return Container(
);
}
}
The widget is assigned its state (_ExampleState) when the createState()
method is called.
As soon as it is assigned its state, the widget becomes mounted.
Why is that important?
When a widget is unmounted in the dispose method of a StatefulWidget
, it loses its state. This happens when it is no longer in the tree. I.e, it is has been closed, or no longer exists.
@override
void unmount() {
super.unmount();
state.dispose();
assert(() {
if (state._debugLifecycleState == _StateLifecycle.defunct)
return true;
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('${state.runtimeType}.dispose failed to call super.dispose.'),
ErrorDescription(
'dispose() implementations must always call their superclass dispose() method, to ensure '
'that all the resources used by the widget are fully released.'
),
]);
}());
// This is the key
state._element = null;
}
This basically means the state can't be updated and setState can no longer be called. So when you check if a widget is mounted, you're checking if its state can still be updated.
Use case:
Going back to our example Stateful Widget example, let's say we had a number that we wanted to update 30 seconds after the Widget is created.
class Example extends StatefulWidget {
@override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
int count = 0;
@override
void initState() {
Future.delayed(const Duration(seconds: 30), () {
setState(() => count = 5);
});
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('count $count'),
));
}
}
Our code will work fine, as long as the widget is disposed of or closed. If it is disposed of, we will get the famous error:
setState() called after dispose()
To prevent this, all we have to do is check if our widget still has state before updating it.
@override
void initState() {
Future.delayed(const Duration(seconds: 30), () {
if (mounted) setState(() => count = 5);
});
super.initState();
}

- 3,296
- 18
- 50
-
Great explanation, thank you so much for sharing it! – Roberto Juárez Mar 01 '22 at 21:11
-
Thanks for your explanation. However, how about avoiding this as an anti-pattern? https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html – Hyo Nov 26 '22 at 14:49
It represents whether a state is currently in the widget tree.
https://api.flutter.dev/flutter/widgets/State/mounted.html
You shouldn't call setState()
on a state that is not currently in the tree.
Edit: The other answer provides a simple example. I should also mention that the described behavior is evident from the StatefulWidget lifecycle: https://flutterbyexample.com/lesson/stateful-widget-lifecycle
It's opinionated, but as far as I can see, it's a rare ocasion when you have to check for mounted
, because you unsubscribe from outside events in dispose()
. Even the Future from the example could be wrapped in CancelableOperation
to cancel it in dispose()
, which is before mounted == false

- 767
- 1
- 5
- 16