InheritedWidget helps share data easily across many parts of a Flutter app without passing it manually everywhere.
InheritedWidget concept in Flutter
class MyData extends InheritedWidget { final int value; const MyData({required this.value, required Widget child, Key? key}) : super(key: key, child: child); static MyData? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType<MyData>(); } @override bool updateShouldNotify(MyData oldWidget) { return oldWidget.value != value; } }
The of method is used by child widgets to access the shared data.
updateShouldNotify tells Flutter when to rebuild widgets that depend on this data.
class CounterData extends InheritedWidget { final int count; const CounterData({required this.count, required Widget child, Key? key}) : super(key: key, child: child); static CounterData? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType<CounterData>(); } @override bool updateShouldNotify(CounterData oldWidget) { return oldWidget.count != count; } }
final data = MyData(value: 42, child: SomeWidget());
of method.final myData = MyData.of(context); if (myData != null) { print(myData.value); }
This app uses MyData to share a counter value. Pressing the button increases the counter, and the text updates automatically.
import 'package:flutter/material.dart'; class MyData extends InheritedWidget { final int value; const MyData({required this.value, required Widget child, Key? key}) : super(key: key, child: child); static MyData? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType<MyData>(); } @override bool updateShouldNotify(MyData oldWidget) { return oldWidget.value != value; } } void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { int counter = 0; void increment() { setState(() { counter++; }); } @override Widget build(BuildContext context) { return MyData( value: counter, child: MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('InheritedWidget Example')), body: const Center(child: CounterDisplay()), floatingActionButton: FloatingActionButton( onPressed: increment, child: const Icon(Icons.add), ), ), ), ); } } class CounterDisplay extends StatelessWidget { const CounterDisplay({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final data = MyData.of(context); return Text('Counter value: ${data?.value ?? 0}', style: const TextStyle(fontSize: 24)); } }
InheritedWidget is immutable; to update data, rebuild it with new values.
Widgets that use of will rebuild when updateShouldNotify returns true.
InheritedWidget is a low-level tool; many apps use higher-level state management packages built on it.
InheritedWidget shares data down the widget tree without manual passing.
Use the of method to access shared data in child widgets.
Widgets rebuild automatically when shared data changes if updateShouldNotify returns true.
Practice
InheritedWidget in Flutter?Solution
Step 1: Understand the role of InheritedWidget
InheritedWidget is designed to share data with its child widgets efficiently.Step 2: Compare with other options
Animations, user input, and network requests are handled by other Flutter classes, not InheritedWidget.Final Answer:
To share data efficiently down the widget tree without passing it manually. -> Option DQuick Check:
InheritedWidget shares data down the tree = C [OK]
- Confusing InheritedWidget with animation or input handling
- Thinking it manages network calls
- Assuming it rebuilds widgets manually
InheritedWidget named MyData inside a child widget?Solution
Step 1: Recall the standard access method
The convention to access InheritedWidget data is using a staticofmethod.Step 2: Verify method names
OnlyMyData.of(context)follows Flutter's standard pattern; others are incorrect.Final Answer:
MyData.of(context) -> Option BQuick Check:
Use of() method to access InheritedWidget data = A [OK]
- Using non-existent methods like get or fetch
- Trying to access data without context
- Confusing with Provider package syntax
MyInheritedWidget updates its data and updateShouldNotify returns true?
class MyInheritedWidget extends InheritedWidget {
final int data;
MyInheritedWidget({required this.data, required Widget child}) : super(child: child);
static MyInheritedWidget? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
}
@override
bool updateShouldNotify(MyInheritedWidget oldWidget) {
return data != oldWidget.data;
}
}
// In a child widget's build:
final inherited = MyInheritedWidget.of(context);
print('Data is: ${inherited?.data}');Solution
Step 1: Understand updateShouldNotify behavior
WhenupdateShouldNotifyreturns true, dependent widgets rebuild and get new data.Step 2: Analyze the print statement
The child widget accesses the updateddatavalue, so it prints the new data.Final Answer:
Data is: new data value -> Option CQuick Check:
updateShouldNotify true triggers rebuild with new data = A [OK]
- Assuming old data is printed after update
- Thinking no rebuild happens
- Expecting runtime errors from updateShouldNotify
InheritedWidget implementation:
class MyData extends InheritedWidget {
final int value;
MyData({required this.value, required Widget child}) : super(child: child);
static MyData of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<MyData>()!;
}
@override
bool updateShouldNotify(MyData oldWidget) {
return false;
}
}Solution
Step 1: Check updateShouldNotify logic
Returning false always means widgets depending on this InheritedWidget won't rebuild on data change.Step 2: Verify other parts
Constructor calls super correctly; of() returns non-null with !; value can be final.Final Answer:
updateShouldNotify always returns false, so dependents never rebuild. -> Option AQuick Check:
False updateShouldNotify blocks rebuilds = D [OK]
- Ignoring updateShouldNotify effect on rebuild
- Thinking constructor call is missing
- Confusing nullable return types
- Assuming value must be mutable
InheritedWidget. Which approach correctly ensures that widgets rebuild only when the color changes?
class ThemeColor extends InheritedWidget {
final Color color;
ThemeColor({required this.color, required Widget child}) : super(child: child);
static ThemeColor? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<ThemeColor>();
}
@override
bool updateShouldNotify(ThemeColor oldWidget) {
// What should go here?
}
}Solution
Step 1: Understand updateShouldNotify purpose
This method decides if dependents rebuild when data changes.Step 2: Compare current and old color values
Return true only if the color changed to trigger rebuilds correctly.Step 3: Evaluate options
return color != oldWidget.color; returns true if colors differ, which is correct. return true; always rebuilds unnecessarily, return false; never rebuilds, return oldWidget.color == null; is irrelevant.Final Answer:
return color != oldWidget.color; -> Option AQuick Check:
Rebuild only if color changes = B [OK]
- Always returning true causing unnecessary rebuilds
- Always returning false blocking updates
- Checking for null instead of value change
Ready to prove it?
Pass the test and this pattern moves unknown
