Sparround

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:

  • Readingcontext.dependOnInheritedWidgetOfExactType<MyScope>(). That call both returns the value and subscribes the current element to that InheritedWidget.
  • Notifying — when the widget is rebuilt, Flutter calls updateShouldNotify(oldWidget). If it returns true, every subscribed element is rebuilt via markNeedsBuild.
dart
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.

ClassWhat it gives youTypical 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 aboutSeveral independent values in one scope
`InheritedNotifier`Wires a `Listenable` into the tree: when the notifier fires, dependents rebuildA 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