What is InheritedWidget and how does it enable state propagation?
Short Answer
InheritedWidget lets data be efficiently passed down the widget tree without manually threading it through every constructor, and it's the low-level mechanism Provider, Theme, and MediaQuery are all built on.
A normal widget passes data to children only via constructor parameters, which gets unwieldy for data needed by many widgets at different depths (theme, locale, app-wide state). InheritedWidget solves this by making itself available to any descendant via context.dependOnInheritedWidgetOfExactType<T>() — the descendant registers as a dependent, and when the InheritedWidget rebuilds with different data, only the widgets that actually depend on it (not the whole subtree) rebuild.
The key method to override is updateShouldNotify(oldWidget), which decides whether dependents should rebuild — typically comparing the new and old data for equality. This selective-rebuild mechanism is exactly why Theme.of(context) or MediaQuery.of(context) are cheap to call in many widgets: only the ones whose relevant data actually changed re-render.
Common Mistakes
- ×Calling dependOnInheritedWidgetOfExactType outside build() without it working as expected — it should be called from build or didChangeDependencies.
- ×Assuming InheritedWidget rebuilds the entire subtree — it only rebuilds registered dependents.
Interview Tips
- →Mention that Provider, Theme.of, and MediaQuery.of are all built on InheritedWidget — shows you understand the layering, not just the Provider package in isolation.