# Lifting State and InheritedWidget — Flutter

Source: https://www.skillbyai.com/en/flutter/s-lifting

> 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.

![Three ideas: lifting state and InheritedWidget, Provider with ChangeNotifier, Riverpod and Bloc.](assets/figures/flutter/section-6-map.svg) — Figure 6.1 — State lifted up, exposed down, rebuilt where needed.

## A minimal InheritedWidget

Exposing a value to descendants.

```dart
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.

**Quiz:** What happens when an InheritedWidget changes and updateShouldNotify returns true?

- [ ] Nothing until hot reload
- [ ] The whole app restarts
- [x] 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.
