Using Flutter’s InheritedWidget to hold app state

  • How do widgets know about the available InheritedWidgets in the ancestor line?
  • How do widgets subscribe to changes in one of those InheritedWidgets?
  • When an InheritedWidget changes, how is that change transmitted to the dependent widgets down the tree?

How do widgets know about the available InheritedWidgets in the ancestor line?

A widget/element has always at this disposal a reference to the list of InheritedWidgets available in its ancestor line. They are stored in the _inheritedWidgets member together with its corresponding type.

Map<Type, InheritedElement> _inheritedWidgets;
void activate() {

_updateInheritance();

}
void _updateInheritance() {
_inheritedWidgets = _parent?._inheritedWidgets;
}
_inheritedWidgets[widget.runtimeType] = this;

How do widgets subscribe to changes in one of the available InheritedWidgets?

When a widget down the tree needs to depend on an InheritedWidget of a given type higher up in the hierarchy, the method inheritFromWidgetOfExactType(type) is called, normally inside the of(context) method. Here the following actions are performed:

  • The desired ancestor is searched in the _inheritedWidgets map
  • and the widget adds itself to the _dependents of the ancestor InheritedWidget.
InheritedWidget inheritFromWidgetOfExactType(Type targetType) {

final InheritedElement ancestor = _inheritedWidgets == null ? null : _inheritedWidgets[targetType];
if (ancestor != null) {

ancestor._dependents.add(this);

}

}

How is the change in the InheritedWidget transmitted to the dependent widgets down the tree?

When an InheritedWidget changes, its update() method is called.

void update(newWidget) {

notifyClients(oldWidget);

rebuild();
}
void notifyClients(oldWidget) {
if (!widget.updateShouldNotify(oldWidget))
return;

for (Element dependent in _dependents) {

dependent.didChangeDependencies();
}
}
void didChangeDependencies() {

markNeedsBuild();
}

Notify state changes down the tree

One important thing to take from above is that with the internal notification scheme implemented in InheritedWidget [based onupdateShouldNotify()] all dependent widgets will be notified of the exact same change in the InheritedWidget.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store