use_setstate_synchronously
This rule flags setState called after an await with no mounted guard in between.
This is a real crash, not a style preference. Between the await and the line after it the widget can be disposed — the user navigated back, a parent rebuilt without this child, a list item scrolled out of a ListView. Calling setState on a disposed State throws setState() called after dispose(), and it does so only under the timing that makes it hard to reproduce and easy to ship.
This is the State counterpart to use_ref_read_synchronously, and it shares that rule’s async-gap machinery. It applies inside any State subclass, including additional bases named through state_base_classes.
This rule is in the recommended preset.
Future<void> load() async { final data = await repository.fetch(); setState(() => _data = data); // the widget may be gone}Future<void> load() async { final data = await repository.fetch(); if (!mounted) return;
setState(() => _data = data);}Configuration
Section titled “Configuration”This rule is on with preset: recommended or preset: opinionated.
Options
Section titled “Options”many_lints: rules: use_setstate_synchronously: state_base_classes: []rules: use_setstate_synchronously: state_base_classes: []| Option | Type | Default | Description |
|---|---|---|---|
state_base_classes |
list | [] |
Additional base classes to treat as a State |
Turning this rule off
Section titled “Turning this rule off”To disable this rule:
rules: use_setstate_synchronously: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”use_ref_and_state_synchronously— Check ref.mounted before using ref or state after an await.use_ref_read_synchronously— Add a mounted guard before calling ref.read after an await.check_is_not_closed_after_async_gap— Check isClosed before emitting state after an await.require_atomic_async_updates— Re-read shared state after an await instead of writing back a stale value.