In Flutter, a StatefulWidget
or a StatelessWidget
can be rebuilt multiple times during its lifetime. Unwanted widget builds can occur for various reasons, such as changes in the widget’s data, changes in the widget’s parent, or changes in the app’s state.
Here are some common ways to deal with unwanted widget builds in Flutter:
- Use
StatefulWidget
only when necessary: If the widget’s state doesn’t change, you can use aStatelessWidget
instead of aStatefulWidget
. This way, the widget won’t be rebuilt unnecessarily. - Use
setState
judiciously: If you need to use aStatefulWidget
, make sure to usesetState
only when it’s necessary.setState
triggers a rebuild of the widget, so you want to avoid calling it unnecessarily. - Use
const
constructor: If you have aStatelessWidget
that takes a constant value, you can use aconst
constructor. This way, the widget won’t be rebuilt if the value doesn’t change. - Avoid using
InheritedWidget
: If possible, try to avoid usingInheritedWidget
to pass data between widgets.InheritedWidget
can trigger unnecessary rebuilds of the widget tree, especially if the data changes frequently. - Use
Consumer
instead ofInheritedWidget
: If you need to useInheritedWidget
, you can useConsumer
to rebuild only the widgets that depend on the data. - Avoid expensive calculations in build methods: If your build method contains expensive calculations, these calculations will be performed every time the widget is rebuilt. Try to move these calculations to a separate method and cache the results if possible.
- Here’s an example that demonstrates the use of a
Consumer
to rebuild only the widgets that depend on the data:
class MyInheritedWidget extends InheritedWidget {
final int data;
MyInheritedWidget({
Key key,
@required this.data,
@required Widget child,
}) : super(key: key, child: child);
@override
bool updateShouldNotify(MyInheritedWidget oldWidget) =>
oldWidget.data != data;
}
class MyChildWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final data = context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>().data;
return Text('Data: $data');
}
}
class MyParentWidget extends StatelessWidget {
final int data;
MyParentWidget({
Key key,
@required this.data,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return MyInheritedWidget(
data: data,
child: Consumer<MyInheritedWidget>(
builder: (context, widget, child) => child,
child: MyChildWidget(),
),
);
}
}