Skip to main content

use_build_context_synchronously

Learn about the use_build_context_synchronously linter rule.

Stable
Flutter

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's context property, the State's mounted property must be checked.
  • For other BuildContext instances (like a local variable or function argument), the BuildContext's mounted property must be checked.

BAD:

dart
void onButtonTapped(BuildContext context) async {  await Future.delayed(const Duration(seconds: 1));  Navigator.of(context).pop(); } 

GOOD:

dart
void onButtonTapped(BuildContext context) {  Navigator.of(context).pop(); } 

GOOD:

dart
void onButtonTapped(BuildContext context) async {  await Future.delayed(const Duration(seconds: 1));   if (!context.mounted) return;  Navigator.of(context).pop(); } 

GOOD:

dart
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:

analysis_options.yaml
yaml
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:

analysis_options.yaml
yaml
linter:  rules:  use_build_context_synchronously: true