use_build_context_synchronously
Do not use BuildContext
across asynchronous gaps.
Details
#DON'T use BuildContext
across asynchronous gaps.
Storing BuildContext
for later usage can easily lead to difficult-to-diagnose crashes. Asynchronous gaps are implicitly storing BuildContext
and are some of the easiest to overlook when writing code.
When a BuildContext
is used, a mounted
property must be checked after an asynchronous gap, depending on how the BuildContext
is accessed:
- When using a
State
'scontext
property, theState
'smounted
property must be checked. - For other
BuildContext
instances (like a local variable or function argument), theBuildContext
'smounted
property must be checked.
BAD:
void onButtonTapped(BuildContext context) async {
await Future.delayed(const Duration(seconds: 1));
Navigator.of(context).pop();
}
GOOD:
void onButtonTapped(BuildContext context) {
Navigator.of(context).pop();
}
GOOD:
void onButtonTapped(BuildContext context) async {
await Future.delayed(const Duration(seconds: 1));
if (!context.mounted) return;
Navigator.of(context).pop();
}
GOOD:
abstract class MyState extends State<MyWidget> {
void foo() async {
await Future.delayed(const Duration(seconds: 1));
if (!mounted) return; // Checks `this.mounted`, not `context.mounted`.
Navigator.of(context).pop();
}
}
Enable
#To enable the use_build_context_synchronously
rule, add use_build_context_synchronously
under linter > rules in your analysis_options.yaml
file:
linter:
rules:
- use_build_context_synchronously
If you're instead using the YAML map syntax to configure linter rules, add use_build_context_synchronously: true
under linter > rules:
linter:
rules:
use_build_context_synchronously: true
Unless stated otherwise, the documentation on this site reflects Dart 3.6.2. Page last updated on 2025-01-27. View source or report an issue.