Remember to use InheritedWidget to think
Inheritedwidgets are an essential component of a project that shares user data. The cliche Provider framework is also implemented based on InheritedWidget
Introduction to the
The InheritedWidget component is a functional bureau that shares data from top to bottom. As the child components to BuildContext. DependOnInheritedWidgetOfExactType method to get data from the parent component.
It’s worth mentioning that this top-down approach to providing book-sharing data is the opposite of Notification delivery. The similarity is that both are initiated by child components. InheritedWidget is an InheritedWidget that uses content to look up data up the tree, and Notification is an InheritedWidget that uses content to initiate notifications up.
The characteristics of
- Child component pass
[BuildContext.dependOnInheritedWidgetOfExactType]
Method to find the corresponding nearestInheritedWidget
And get the data. InheritedWidget
To provide by custom or agreementof
Static method to make it easier for child components to get data. This method does not necessarily return the inherited widget; it can also return other data.- call
of
Method components must be in theInheritedWidget
Inside. If used in the same widget, you can passBuilder
Wrap the components you need to use.
role
In use, we find that the InheritedWidget uses the parent component to provide data, and the child component can search the corresponding shared data from the bottom up, which is intuitive.
A common way to update data incorrectly
SetState: We’ve seen a lot of articles online about using inheritedWidgets and updating data. But this just shows what this component does. The vast majority share data with final declarations within the InheritedWidget component. Then the parent component is forced to refresh by setState in the parent component, and the InheritedWidget component is also refreshed. Of course, its multi-layer child components are also rebuilt, causing a lot of unnecessary consumption.
How to optimize?
Inheritedwidgets provide data sharing, avoiding the need for data to be passed through layers of claims from top to bottom. It’s also very clear where we use the data. The next thing to do is to have the specified component update the data after it is refreshed. ValueNotifier comes to mind: When inheritedWidgets share data, they are wrapped with ValueNotifier, and the data types that inheritedWidgets get from the OF method are also ValueNotifier, implemented with ValueListenableBuilder where they are used.
Think further
As mentioned in the InheritedWidget article in the source code Analysis series of Flutter, modify the of method:
-
dependOnInheritedWidgetOfExactType
-
getElementForInheritedWidgetOfExactType().widget
The difference between the two: Call dependOnInheritedWidgetOfExactType () and getElementForInheritedWidgetOfExactType () difference is that the former will depend on registration, while the latter is not, So the call dependOnInheritedWidgetOfExactType (), InheritedWidget and rely on it and of the sons of component relationship registration is complete, when after InheritedWidget changes, will update depends on its components, That is, the didChangeDependencies() and build() methods that call these descendant components. And when the call is getElementForInheritedWidgetOfExactType (), since there is no registration dependencies, so after when InheritedWidget changes, the children will not update the corresponding Widget.
@override T? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>( {Object? aspect}) { assert(_debugCheckStateIsActiveForAncestorLookup()); final InheritedElement? ancestor = _inheritedWidgets == null ? null : _inheritedWidgets! [T]; If (ancestor! = null) { assert(ancestor is InheritedElement); return dependOnInheritedElement(ancestor, aspect: aspect) as T; } _hadUnsatisfiedDependencies = true; return null; } @override InheritedElement? getElementForInheritedWidgetOfExactType<T extends InheritedWidget>() { assert(_debugCheckStateIsActiveForAncestorLookup()); final InheritedElement? ancestor = _inheritedWidgets == null ? null : _inheritedWidgets! [T]; return ancestor; }Copy the code
Obviously changed to getElementForInheritedWidgetOfExactType < T > () the widget, will need a non less, also is a good thing.
Further reflection leads to doubt
Since ValueNotifier is used to combine the InheritedWidget with the InheritedWidget, when we change the value of ValueNotifier to change the page, the InheritedWidget component is not rebuilt and does not trigger updateShouldNotify. Even in child components that use data, the didChangeDependencies method is not called when value changes. So exactly how the OF method is implemented depends on the business design.
The pictures in the article are borrowed fromSource Code Analysis series InheritedWidget