dependOnInheritedWidgetOfExactType<T extends InheritedWidget> method

  1. @override
T? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({
  1. Object? aspect,
})
inherited

Returns the nearest widget of the given type T and creates a dependency on it, or null if no appropriate widget is found.

The widget found will be a concrete InheritedWidget subclass, and calling dependOnInheritedWidgetOfExactType registers this build context with the returned widget. When that widget changes (or a new widget of that type is introduced, or the widget goes away), this build context is rebuilt so that it can obtain new values from that widget.

This is typically called implicitly from of() static methods, e.g. Theme.of.

This method should not be called from widget constructors or from State.initState methods. While calling this method effectively registers the BuildContext as a dependent for future rebuilds, the constructor and State.initState are lifecycle-locked and only execute once during the initial creation of the element.

If an inherited value changes later, the framework will correctly trigger the State.build method to run again, but it cannot re-run the constructor or State.initState. Consequently, if any internal variables, controllers, or side effects were initialized using a "snapshot" of the inherited value in those one-time methods, they will retain their original, now-obsolete values. This leads to a state desynchronization where the widget's State.build method might be using updated data while its internal logic remains bound to stale data captured during State.initState.

To ensure the widget stays in sync, call this (directly or indirectly) from build methods, layout and paint callbacks, or from State.didChangeDependencies.

State.didChangeDependencies is called immediately after State.initState and is re-invoked whenever the inherited widget this context depends on changes, until the next time the widget or one of its ancestors is moved (for example, because an ancestor is added or removed). This allows the State to update internal variables or perform initialization logic that depends on the inherited value before State.build is called.

This method should not be called from State.dispose because the element tree is no longer stable at that time. To refer to an ancestor from that method, save a reference to the ancestor in State.didChangeDependencies. It is safe to use this method from State.deactivate, which is called whenever the widget is removed from the tree.

It is also possible to call this method from interaction event handlers (e.g. gesture callbacks) or timers, to obtain a value once, as long as that value is not cached and/or reused later.

Calling this method is O(1) with a small constant factor, but will lead to the widget being rebuilt more often.

The aspect parameter is only used when T is an InheritedWidget subclasses that supports partial updates, like InheritedModel. It specifies what "aspect" of the inherited widget this context depends on.

Implementation

@override
T? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({Object? aspect}) {
  assert(_debugCheckStateIsActiveForAncestorLookup());
  final InheritedElement? ancestor = _inheritedElements?[T];
  if (ancestor != null) {
    return dependOnInheritedElement(ancestor, aspect: aspect) as T;
  }
  _hadUnsatisfiedDependencies = true;
  return null;
}