InheritedWidget: the base of every library
InheritedWidget is Flutter's own mechanism for passing data down the widget tree. The official docs describe it as the low-level approach used to communicate between ancestors and children in the widget tree; this is what `package:provider` and many other approaches use under the hood.
It has two moves:
- Reading —
context.dependOnInheritedWidgetOfExactType<MyScope>(). That call both returns the value and subscribes the current element to thatInheritedWidget. - Notifying — when the widget is rebuilt, Flutter calls
updateShouldNotify(oldWidget). If it returnstrue, every subscribed element is rebuilt viamarkNeedsBuild.
class ThemeScope extends InheritedWidget {
const ThemeScope({
super.key,
required this.isDark,
required super.child,
});
final bool isDark;
/// Ənənəvi `of` pattern-i: oxuyan həm dəyəri alır, həm abunə olur.
static ThemeScope of(BuildContext context) {
final scope = context.dependOnInheritedWidgetOfExactType<ThemeScope>();
assert(scope != null, 'ThemeScope tapılmadı — ağacın yuxarısına əlavə edin');
return scope!;
}
/// Yalnız bu şərt true olduqda abunəçilər rebuild olunur.
@override
bool updateShouldNotify(ThemeScope oldWidget) => isDark != oldWidget.isDark;
}
// İstifadə: rebuild yalnız isDark dəyişdikdə baş verir.
final isDark = ThemeScope.of(context).isDark;A minimal InheritedWidget — the whole of Provider's "magic" is these 20 lines.
| Class | What it gives you | Typical use |
|---|---|---|
| `InheritedWidget` | O(1) lookup in the tree plus all-or-nothing notification via `updateShouldNotify` | Configuration that is immutable or changes rarely |
| `InheritedModel` | Notification split into aspects — a dependent only wakes for the part it cares about | Several independent values in one scope |
| `InheritedNotifier` | Wires a `Listenable` into the tree: when the notifier fires, dependents rebuild | A hand-rolled scope backed by a `ValueNotifier`/`ChangeNotifier` |
The key sentence for an interview: package:provider describes itself as "a wrapper around InheritedWidget to make them easier to use and more reusable", and package:flutter_bloc implements BlocProvider, MultiBlocProvider and RepositoryProvider with package:provider, re-exporting its context.read/watch/select extensions. So "Provider or BLoC?" is really "which wrapper over the same mechanism?".
📚 Sources and documentation
- State management options (InheritedWidget section)officialdocs.flutter.dev
The official text stating that InheritedWidget is what other approaches use under the hood.
- InheritedWidget API docsofficialapi.flutter.dev
- package:providerofficialpub.dev
The package's own description: a wrapper around InheritedWidget.
- flutter_bloc: extension methodsofficialbloclibrary.dev
The section showing that flutter_bloc depends on package:provider and re-exports its extensions.