Contents

use_build_context_synchronously

Contents

Do not use BuildContext across asynchronous gaps.

This rule is available as of Dart 2.13.

Rule sets: flutter

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();
  }
}

Usage

#

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