تكرار السؤال: …
الإجابة المختصرة
يحتفظ كل Element بجدول تجزئة موروث (Map<Type, InheritedElement>) يمرره للأبناء، مما يجعل البحث O(1) فورياً، ويقوم الـ InheritedElement بتسجيل الـ Elements التابعة في Set لتحديثها عند تغير البيانات.
الشرح
بدلاً من التسلق لأعلى الشجرة خطوة بخطوة عند استدعاء of(context)، يمتلك كل Element حقلاً داخلياً _inheritedElements يحتوي على خريطة بكل أنواع InheritedWidgets المتوفرة في أسلافه تم نسخها وإثراؤها أثناء مرحلة mount(). عند استدعاء dependOnInheritedWidgetOfExactType<T>()، يقرأ المرجع في O(1) ويسجل الـ context الحالي في قائمة الـ dependents الخاصة بذلك الـ InheritedElement. عند استدعاء updateShouldNotify() وترجع true، يطلب الـ InheritedElement عمل markNeedsBuild() فقط لتلك العناصر المسجلة.
مثال بالكود
class MyTheme extends InheritedWidget {
const MyTheme({super.key, required this.color, required super.child});
final Color color;
// Registers `context` as a dependent: it rebuilds whenever updateShouldNotify returns true.
static MyTheme of(BuildContext context) =>
context.dependOnInheritedWidgetOfExactType<MyTheme>()!;
// Reads the value once without subscribing to future changes.
static Color peek(BuildContext context) =>
(context.getElementForInheritedWidgetOfExactType<MyTheme>()!.widget as MyTheme).color;
@override
bool updateShouldNotify(MyTheme oldWidget) => color != oldWidget.color;
}أخطاء شائعة
- استدعاء dependOnInheritedWidgetOfExactType داخل دالة initState()، مما يرمي خطأ صريحاً لأن الـ Element لم يكتمل ربطه وتجهيزه للتسجيل في قائمة التبعيات.