What is Flutter InheritedWidget?
The InheritedWidget pattern is one of the most powerful features in Flutter, especially for large applications. In Flutter, widgets can contain other widgets, creating a widget tree. This tree can become very large, especially in large applications and each widget may need access to some data or state.
An example can be considered where important data is passed from a parent widget to a child widget. For a small application, it’s easy to handle passing the data down to multiple children. However, for large applications, it becomes difficult to pass data. Now consider data modification and updating all the children with updated information.
InheritedWidget is a Flutter widget that can provide data to all the descendant’s widgets in the widget tree. InheritedWidget provides data that can be accessed by any descendant widget without explicit data passing through intermediary widgets. This especially helps in reducing complexity in the large widget tree.
Upon updating an InheritedWidget, it notifies all of its descendants about the changes. Only the child widgets that rely on the modified data are rebuilt after an update to optimize performance. When only relevant widgets need to be regenerated, rather than the entire widget tree, this leads to significant performance improvements.
Example
Let’s understand InheritedWidget using an example. Let’s create a class MyData
that contains a value which is the data that we want to pass to all of its children. MyData overrides the updateShouldNotify function. This function returns true if the value has changed. Once Flutter detects changes, any child widget that depends on value
will be rebuilt.
class MyData extends InheritedWidget {
final int value;
MyData({this.value, Widget child}) : super(child: child);
@override
bool updateShouldNotify(MyData oldWidget) => value != oldWidget.value;
}
Next, wrap your top-level widget with the MyData
widget to make data available for all child widgets.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MyData(
value: 42,
child: MaterialApp(
title: 'MyApp',
home: MyHomePage(),
),
);
}
}
Now we can access the data in any child widget using the of
method provided by InheritedWidget
. MyData.of(context)
can be used to access MyData
widget from the widget tree and access its values.
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final myData = MyData.of(context);
return Scaffold(
appBar: AppBar(title: Text('MyHomePage')),
body: Center(child: Text('MyData value is ${myData.value}')),
);
}
}
Conclusion
In conclusion, the InheritedWidget pattern in Flutter provides a way to efficiently pass data and state to all the children in the widget tree. This leads to excellent performance optimization, especially in a large widget tree, since only the widgets which are directly dependent on the updated data or state are rebuilt. You can check out the official Flutter Doc for more details.