Skip to content

proposal: use_set_state_synchronously #59410

@navaronbracke

Description

@navaronbracke

use_set_state_synchronously

I propose a new lint, akin to its counterpart, use_build_context_synchronously, but for setState() invocations.

Description

Use setState() synchronously and guard it with a mounted check if needed.

Details

Using setState() after an async gap is potentially unsafe. Consider guarding it with a mounted check.

We should consider both explicit awaits and sync/async versions of the then/catchError/whenComplete callbacks.

Kind

It guards against errors.

Bad Examples

await Future.value(42);

setState(() {});
await Future.value(42).then((int value) {
  setState(() {});
});
await Future.value(42).then((int value) async {
  await Future<void>.delayed(const Duration(seconds: 1));

  setState(() {});
});
await Future.value(42).catchError((Object error, StackTrace stackTrace) {
  setState(() {});
});
await Future.value(42).whenComplete(() {
  setState(() {});
});

Good Examples

await Future.value(42);

if (mounted) {
  setState(() {});
}
await Future.value(42);

if (!mounted) {
  return;
}

setState(() {});
await Future.value(42);

if (!context.mounted) {
  return;
}

setState(() {});
await Future.value(42).then((int value) {
  if (!mounted) {
    return;
  }
  
  setState(() {});
});
await Future.value(42).then((int value) async {
  await Future<void>.delayed(const Duration(seconds: 1));
  
  if (!mounted) return;

  setState(() {});
});
await Future.value(42).catchError((Object error, StackTrace stackTrace) {
  if (!mounted) {
    return;
  }
  
  setState(() {});
});
await Future.value(42).whenComplete(() {
  if (!mounted) {
    return;
  }

  setState(() {});
});

Discussion

I have seen bugs (both in the framework and in user code) due to bad usages of setState() after an async gap.

I.e. flutter/flutter#124597

Discussion checklist

  • List any existing rules this proposal modifies, complements, overlaps or conflicts with.
  • List any relevant issues (reported here, the SDK Tracker, or elsewhere).
  • If there's any prior art (e.g., in other linters), please add references here.
  • If this proposal corresponds to Effective Dart or Flutter Style Guide advice, please call it out. (If there isn't any corresponding advice, should there be?)
  • If this proposal is motivated by real-world examples, please provide as many details as you can. Demonstrating potential impact is especially valuable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3A lower priority bug or feature requestarea-devexpFor issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages.devexp-linterIssues with the analyzer's support for the linter packagelinter-lint-proposallinter-set-flutterlinter-status-pendingtype-enhancementA request for a change that isn't a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions