Lesson 16 / 25
Lifting State and InheritedWidget
The mechanism under every state library.
Ephemeral versus app state
Ephemeral state (the current tab, an animation, a text field) belongs in a single StatefulWidget. App state (the signed-in user, a cart, settings) is needed by many widgets, so you lift it up to a common ancestor and pass it down. Passing through every constructor ("prop drilling") gets tedious, so Flutter offers InheritedWidget: descendants call context.dependOnInheritedWidgetOfExactType<T>() to read it and are registered as dependents, so when it is replaced and updateShouldNotify returns true they rebuild. Theme.of and MediaQuery.of work this way, and Provider, Riverpod and Bloc build on the same idea of exposing state down the tree.
Share state without the mess
Ephemeral state lives in a widget; app state is lifted up and exposed to the widgets that need it.
A minimal InheritedWidget
Exposing a value to descendants.
class UserScope extends InheritedWidget {
const UserScope({super.key, required this.user, required super.child});
final User user;
static User of(BuildContext context) {
final scope = context.dependOnInheritedWidgetOfExactType<UserScope>();
assert(scope != null, 'No UserScope found in context');
return scope!.user;
}
@override
bool updateShouldNotify(UserScope oldWidget) => user != oldWidget.user;
}
// usage deep in the tree
Text('Hi ${UserScope.of(context).name}');A building intercom
Instead of passing a note through every flat on the way down, the ground floor announces it on the intercom and only the flats that subscribed hear the update.
Quick check: What happens when an InheritedWidget changes and updateShouldNotify returns true?
- Nothing until hot reload
- The whole app restarts
- Widgets that depend on it via dependOnInheritedWidgetOfExactType rebuild
- Only the root widget rebuilds
Answer
Widgets that depend on it via dependOnInheritedWidgetOfExactType rebuild — Dependents are tracked and rebuilt automatically.