avoid-returning-widgets
added in: 1.0.0 warning
Warns when a method, function or getter returns a Widget or subclass of a Widget.
Extracting widgets to a method is considered as a Flutter anti-pattern, because when Flutter rebuilds widget tree, it calls the function all the time, making more processor time for the operations.
Consider creating a separate widget instead of a function or method.
The following patterns will not trigger the rule:
- Widget build method overrides.
- Class method that is passed to a builder.
- Functions with functional_widget package annotations.:::
Additional resources:
- [https://github.com/flutter/flutter/issues/19269]
- [https://flutter.dev/docs/perf/rendering/best-practices#controlling-build-cost]
- [https://www.reddit.com/r/FlutterDev/comments/avhvco/extracting_widgets_to_a_function_is_not_an/]
- [https://medium.com/flutter-community/splitting-widgets-to-methods-is-a-performance-antipattern-16aa3fb4026c]
Config
Set ignored-names
(default is none) to ignore a function or method name.
Set ignored-annotations
(default is [FunctionalWidget
, swidget
, hwidget
, hcwidget
]) to override default ignored annotation list.
Set allow-nullable
to allow functions or methods with the nullable return type.
dart_code_linter:
...
rules:
...
- avoid-returning-widgets:
ignored-names:
- testFunction
ignored-annotations:
- allowedAnnotation
will ignore all functions named testFunction
and all functions having allowedAnnotation
annotation.
Example
Bad:
class MyWidget extends StatelessWidget {
const MyWidget();
// LINT
Widget _getWidget() => Container();
Widget _buildShinyWidget() {
return Container(
child: Column(
children: [
Text('Hello'),
...
],
),
);
}
@override
Widget build(BuildContext context) {
return Row(
children: [
Text('Text!'),
...
_buildShinyWidget(), // LINT
],
);
}
}
Good:
class MyWidget extends StatelessWidget {
const MyWidget();
@override
Widget build(BuildContext context) {
return Row(
children: [
Text('Text!'),
...
const _MyShinyWidget(),
],
);
}
}
class _MyShinyWidget extends StatelessWidget {
const _MyShinyWidget();
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
Text('Hello'),
...
],
),
);
}
}
Good:
class MyWidget extends StatelessWidget {
Widget _buildMyWidget(BuildContext context) {
return Container();
}
@override
Widget build(BuildContext context) {
return Builder(
builder: _buildMyWidget,
);
}
}