Rules / Complexity / prefer-extracting-callbacks
prefer-extracting-callbacks
lint/complexity/prefer-extracting-callbacksrecommendedflutter
Same as prefer-extracting-callbacks · Dart Code MetricsFlags an inline block-body callback passed to a widget constructor that
should be extracted to a method.
Large inline closures in a build method bloat the widget tree, hurt
readability, and can defeat const-ness; moving them to a named widget method
clarifies intent and eases reuse. The rule only inspects classes that
syntactically extend a Widget or State, and flags block-body
function-expression arguments to widget constructions. Arrow callbacks,
empty blocks, and Flutter builders (whose first parameter is typed
BuildContext) are never flagged.
Options
allowed_line_count (integer, default: none) — when set, only callbacks
spanning more than this many lines are flagged; unset flags every qualifying
callback.
ignored_named_arguments (list of strings, default: empty) —
named-argument labels whose callbacks are ignored.
Invalid
example.dartdart
import 'package:flutter/material.dart';
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
final now = DateTime.now();
doSomething(now);
},
child: const Text('go'),
);
}
}
class MyState extends State<MyWidget> {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {});
doSomething(null);
},
child: const Text('tap'),
);
}
}
void doSomething(Object? x) {}
Prefer extracting the callback to a separate widget method.
8 return ElevatedButton(
9 onPressed: () {
∙
Prefer extracting the callback to a separate widget method.
21 return GestureDetector(
22 onTap: () {
∙
Valid
example.dartdart
import 'package:flutter/material.dart';
// Non-widget class: callbacks are never flagged (dcl only visits Widget/State).
class NotAWidget {
void run(List<int> items) {
items.forEach((item) {
final doubled = item * 2;
print(doubled);
});
}
}
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
return Column(
children: [
// Arrow callback: not a block body, never flagged.
ElevatedButton(
onPressed: () => doSomething(),
child: const Text('go'),
),
// Single-line block callback: within allowed_line_count, not flagged.
ElevatedButton(
onPressed: () { doSomething(); },
child: const Text('short'),
),
// Builder callback (first parameter is BuildContext) is excluded.
Builder(
builder: (BuildContext context) {
final theme = Theme.of(context);
return Text('$theme');
},
),
],
);
}
}
void doSomething() {}
How to configure
Set the severity of prefer-extracting-callbacks in your falcon.json:
falcon.jsonjson
{
"linter": {
"rules": {
"complexity": {
"prefer-extracting-callbacks": "error"
}
}
}
}