avoid_inherited_widget_in_initstate
This rule flags SomeInheritedWidget.of(context) and .maybeOf(context) calls inside a State’s initState method — including Theme.of, MediaQuery.of, Navigator.of, and any custom InheritedWidget.
Why use this rule
Section titled “Why use this rule”Those lookups are backed by dependOnInheritedWidgetOfExactType, which is not valid during initState. At that point the element is not fully mounted, so the call either throws outright or silently registers a dependency that never delivers updates. Either way the widget will not rebuild when the theme, media query, or locale changes.
didChangeDependencies exists exactly for this: it runs once immediately after initState, and again every time an inherited dependency changes.
See also: State.initState docs | State.didChangeDependencies docs
Caching a theme colour at init time. It either throws immediately, or freezes at whatever the theme was when the widget was first inserted and ignores every later theme change:
class _BannerState extends State<Banner> { late final Color _background;
@override void initState() { super.initState(); _background = Theme.of(context).primaryColor; // LINT }
@override Widget build(BuildContext context) => ColoredBox(color: _background);}Any inherited lookup has the same problem — MediaQuery.of, Navigator.of,
Localizations.of, and your own InheritedWidget:
class _SplitViewState extends State<SplitView> { late final bool _isWide;
@override void initState() { super.initState(); _isWide = MediaQuery.of(context).size.width > 600; // LINT }
@override Widget build(BuildContext context) => _isWide ? const Text('wide') : const Text('narrow');}Read it in build, where it re-reads on every rebuild:
class _BannerState extends State<Banner> { @override Widget build(BuildContext context) => ColoredBox(color: Theme.of(context).primaryColor);}When the value genuinely has to be cached — because computing it is expensive,
or because something else needs it in a callback — use
didChangeDependencies. Flutter calls it once right after initState, and
again every time an inherited dependency changes:
class _SplitViewState extends State<SplitView> { late bool _isWide;
@override void didChangeDependencies() { super.didChangeDependencies(); _isWide = MediaQuery.of(context).size.width > 600; }
@override Widget build(BuildContext context) => _isWide ? const Text('wide') : const Text('narrow');}Note the field is late, not late final — didChangeDependencies runs more
than once.
Known limitations
Section titled “Known limitations”Only .of(context) and .maybeOf(context) on a type that is an
InheritedWidget are matched. A helper that wraps the lookup —
AppTheme.current(context) — is not recognised.
The check descends into closures declared inside initState, because a closure
invoked synchronously fails the same way. A lookup inside a closure that
deliberately escapes initState — one passed to
WidgetsBinding.instance.addPostFrameCallback, say — runs after mounting and is
safe, but is still reported. Suppress those with
// ignore: many_lints/avoid_inherited_widget_in_initstate.
Turning this rule off
Section titled “Turning this rule off”This rule is in the recommended preset, so it is on with
preset: recommended or preset: opinionated. Add it to preset: core with
avoid_inherited_widget_in_initstate: true.
To turn it off:
rules: avoid_inherited_widget_in_initstate: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Options
Section titled “Options”Projects with a state abstraction that does not extend Flutter’s State can
opt that base class into this rule:
many_lints: rules: avoid_inherited_widget_in_initstate: state_base_classes: [AppState]rules: avoid_inherited_widget_in_initstate: state_base_classes: [AppState]| Option | Type | Default | Description |
|---|---|---|---|
state_base_classes |
list of strings | [] |
Additional non-State base classes whose subclasses should be treated as state classes |
Related rules
Section titled “Related rules”avoid_empty_setstate— Don’t call setState with an empty callback.avoid_late_context— Don’t read BuildContext in a late field initializer.avoid_mounted_in_setstate— Detect mounted checks inside setState callbacks.avoid_state_constructors— Avoid constructors with logic in State classes.