avoid-read-inside-build

Path
lint/correctness/avoid-read-inside-build
Default
On (recommended)
Origin
Falcon
Domain
provider
Rule
117 of 512
recommendedprovider

Flags non-listening Provider reads directly inside Flutter widget builds.

A read does not rebuild the widget when its value changes. This checks package:provider context extensions and Provider.of(listen: false) on a Flutter BuildContext. Nested callbacks are skipped: their execution phase depends on the receiving API, not their lexical position. BuildWithChild overrides on nested's single-child widgets are also build entry points; didChangeDependencies permits subscriptions but is not a build.

Invalid

example.dartdart
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';
import 'package:nested/nested.dart';

class View extends StatelessWidget {
  Widget build(BuildContext context) {
    context.read<int>();
    final value = (context.read<String>());
    if (true) context.read<bool>();
    Provider.of<int>(context, listen: false);
    return context.read<Widget>();
  }
}
class StatefulView extends StatefulWidget {
  State<StatefulView> createState() => ViewState();
}
class ViewState extends State<StatefulView> {
  Widget build(BuildContext other) {
    return other.read<Widget>();
  }
}

class SingleView extends SingleChildStatelessWidget {
  Widget buildWithChild(BuildContext context, Widget? child) {
    context.read<int>();
    Provider.of<int>(context, listen: false);
    return child ?? SizedBox();
  }
}

class SingleState extends SingleChildState<SingleChildStatefulWidget> {
  Widget buildWithChild(BuildContext context, Widget? child) {
    context.read<int>();
    Provider.of<int>(context, listen: false);
    return child ?? SizedBox();
  }
}
Use watch instead of read for values used during build.
6 Widget build(BuildContext context) {
7 context.read<int>();
Use watch instead of read for values used during build.
7 context.read<int>();
8 final value = (context.read<String>());
Use watch instead of read for values used during build.
8 final value = (context.read<String>());
9 if (true) context.read<bool>();
Use watch instead of read for values used during build.
9 if (true) context.read<bool>();
10 Provider.of<int>(context, listen: false);
Use watch instead of read for values used during build.
10 Provider.of<int>(context, listen: false);
11 return context.read<Widget>();
Use watch instead of read for values used during build.
18 Widget build(BuildContext other) {
19 return other.read<Widget>();
Use watch instead of read for values used during build.
24 Widget buildWithChild(BuildContext context, Widget? child) {
25 context.read<int>();
Use watch instead of read for values used during build.
25 context.read<int>();
26 Provider.of<int>(context, listen: false);
Use watch instead of read for values used during build.
32 Widget buildWithChild(BuildContext context, Widget? child) {
33 context.read<int>();
Use watch instead of read for values used during build.
33 context.read<int>();
34 Provider.of<int>(context, listen: false);

Valid

example.dartdart
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';

class View extends StatelessWidget {
  Widget build(BuildContext context) {
    context.watch<int>();
    Provider.of<int>(context);
    Provider.of<int>(context, listen: true);
    final callback = () => context.read<int>();
    void local() { context.read<int>(); }
    return SizedBox();
  }
  void callback(BuildContext context) { context.read<int>(); }
}
class NotAWidget {
  void build(BuildContext context) { context.read<int>(); }
}
class Other { T read<T>() => throw 0; }
void readOther(Other context) { context.read<int>(); }

class DependentState extends State<StatefulWidget> {
  BuildContext get context => throw 0;
  void didChangeDependencies() {
    context.read<int>();
    Provider.of<int>(context, listen: false);
  }
  Widget helper(BuildContext context) => Text('${context.read<int>()}');
  Widget build(BuildContext context) => helper(context);
}

Configure avoid-read-inside-build

Set its severity in falcon.json. See the configuration guide.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "correctness": {
        "avoid-read-inside-build": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/correctness/avoid-read-inside-build: <reason>