use_ build_ context_ synchronously
Learn about the use_build_context_synchronously linter rule.
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'scontextproperty, theState'smountedproperty must be checked. - For other
BuildContextinstances (like a local variable or function argument), theBuildContext'smountedproperty 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.10.3. Report an issue.