InheritedWidget — یہ کیا ہے، درخت میں ڈیٹا پاس کرنا اور یہ کیسے کام کرتا ہے

مصنف: IT Sectr اشاعت: 2026-07-02 مطالعے کا وقت: 9 منٹ

InheritedWidget Flutter میں ایک خاص ویجٹ ہے جو کنسٹرکٹرز کے ذریعے واضح طور پر پاس کیے بغیر ویجٹ ٹری میں نیچے کی طرف ڈیٹا پاس کرتا ہے۔ چائلڈ ویجٹ BuildContext کے ذریعے ڈیٹا تک رسائی حاصل کرتے ہیں اور خود بخود اپ ڈیٹس کو سبسکرائب کرتے ہیں۔ جب InheritedWidget میں ڈیٹا تبدیل ہوتا ہے، تمام منحصر ویجٹ دوبارہ تعمیر ہوتے ہیں۔ Flutter API Reference, 2025 کے مطابق، InheritedWidget Theme، MediaQuery، Localizations اور زیادہ تر اسٹیٹ مینجمنٹ لائبریریوں کی بنیاد ہے۔

اہم نکات

  • InheritedWidget ہر ویجٹ کے ذریعے واضح طور پر پاس کیے بغیر Widget Tree میں نیچے ڈیٹا پاس کرتا ہے۔
  • خودکار سبسکرپشن — dependOnInheritedWidgetOfExactType استعمال کرنے والے ویجٹ ڈیٹا تبدیل ہونے پر دوبارہ تعمیر ہوتے ہیں۔
  • Theme اور MediaQuery InheritedWidget کی بلٹ ان مثالیں ہیں، جو ہر Flutter ایپلیکیشن میں دستیاب ہیں۔
  • Provider اور Riverpod InheritedWidget کے اوپر بنائے گئے ہیں اور اسٹیٹ مینجمنٹ کے لیے اس کی صلاحیتوں کو بڑھاتے ہیں۔
  • درست نفاذ کے لیے غیر ضروری دوبارہ تعمیر کو روکنے کے لیے updateShouldNotify کو اوور رائڈ کرنا ضروری ہے۔

Flutter میں InheritedWidget کیا ہے؟

InheritedWidget ایک ویجٹ ہے جو اپنے ڈیٹا کو Widget Tree میں تمام اولاد کے لیے دستیاب کرتا ہے۔ عام ویجٹ کے برعکس جو صرف کنسٹرکٹرز کے ذریعے چائلڈ عناصر کو ڈیٹا پاس کرتا ہے، InheritedWidget سب ٹری میں کسی بھی ویجٹ کو پیرامیٹرز کی زنجیر کے بغیر ڈیٹا تک رسائی کی اجازت دیتا ہے۔ یہ “prop drilling” مسئلہ کو حل کرتا ہے — بہت سے درمیانی ویجٹ کے ذریعے ڈیٹا پاس کرنا جو خود اس ڈیٹا کو استعمال نہیں کرتے۔

بلٹ ان InheritedWidget

Flutter میں کئی بلٹ ان InheritedWidget شامل ہیں: Theme (رنگ سکیم اور اسٹائل)، MediaQuery (اسکرین سائز، اورینٹیشن، پکسل کثافت)، Localizations (مقامی سٹرنگز)، Directionality (متن کی سمت)، DefaultTextStyle (ڈیفالٹ متن اسٹائل)۔ یہ ویجٹ MaterialApp جیسے روٹ ویجٹ کے ذریعے سیٹ کیے جاتے ہیں اور پوری ایپلیکیشن میں دستیاب ہوتے ہیں۔

InheritedWidget لائف سائیکل

InheritedWidget کی اپنی کوئی حالت نہیں ہوتی — یہ کنسٹرکٹر کے ذریعے پاس کردہ ڈیٹا کو ذخیرہ کرتا ہے۔ جب InheritedWidget کا پیرنٹ نئے ڈیٹا کے ساتھ دوبارہ تعمیر ہوتا ہے، تو پرانے اور نئے ڈیٹا کا موازنہ کرنے کے لیے updateShouldNotify طریقہ بلایا جاتا ہے۔ اگر طریقہ true لوٹاتا ہے، تو تمام منحصر ویجٹ دوبارہ تعمیر کے لیے نشان زد ہو جاتے ہیں۔ یہ ایک سادہ لیکن موثر رد عمل اپ ڈیٹ میکانزم ہے۔

InheritedWidget کے ذریعے ڈیٹا پاس کرنا کیسے کام کرتا ہے

InheritedWidget کے ذریعے ڈیٹا پاس کرنے کا میکانزم Element Tree پر مبنی ہے۔ جب کوئی ویجٹ dependOnInheritedWidgetOfExactType کو کال کرتا ہے، تو متعلقہ عنصر InheritedElement پر انحصار رجسٹر کرتا ہے۔ جب InheritedWidget تبدیل ہوتا ہے، InheritedElement تمام منحصر عناصر کو مطلع کرتا ہے، جو اگلے فریم میں دوبارہ تعمیر ہوتے ہیں۔

انحصار رجسٹریشن

dependOnInheritedWidgetOfExactType طریقہ صرف درخت میں InheritedWidget تلاش نہیں کرتا — یہ موجودہ عنصر کو اطلاعات سبسکرائب کرتا ہے۔ اگر آپ dependOn کی بجائے findAncestorWidgetOfExactType استعمال کرتے، ویجٹ ڈیٹا حاصل کر لیتا لیکن تبدیل ہونے پر دوبارہ تعمیر نہ ہوتا۔ یہ ایک اہم فرق ہے: dependOn ایک سبسکرپشن ہے، findAncestor ایک بار کی تلاش ہے۔

InheritedWidget کا درخت travers

جب کوئی ویجٹ InheritedWidget کی درخواست کرتا ہے، Flutter موجودہ عنصر سے جڑ تک Element Tree میں اوپر جاتا ہے، قسم کی مماثلت کے لیے ہر InheritedElement کو چیک کرتا ہے۔ پہلا مماثل InheritedElement لوٹایا جاتا ہے۔ اس کا مطلب ہے کہ درخت میں قریب ترین InheritedWidget کو ترجیح حاصل ہے — آپ InheritedWidget کو اولاد کے قریب رکھ کر کسی مخصوص سطح پر ڈیٹا کو اوور رائڈ کر سکتے ہیں۔

dart
class ThemeData {
  final Color primaryColor;
  final TextTheme textTheme;

  const ThemeData({required this.primaryColor, required this.textTheme});
}

class MyTheme extends InheritedWidget {
  final ThemeData data;

  const MyTheme({required this.data, required Widget child}) : super(child: child);

  static MyTheme of(BuildContext context) {
    final widget = context.dependOnInheritedWidgetOfExactType<MyTheme>();
    assert(widget != null, "MyTheme not found in tree");
    return widget!;
  }

  @override
  bool updateShouldNotify(MyTheme oldWidget) => oldWidget.data != data;
}

اس مثال میں، MyTheme اولاد کو ڈیٹا فراہم کرنے کے لیے ایک جامد of طریقہ استعمال کرتا ہے۔ dependOnInheritedWidgetOfExactType طریقہ ایک انحصار رجسٹر کرتا ہے، اور updateShouldNotify پرانے اور نئے ڈیٹا کا موازنہ کرتا ہے تاکہ یہ تعین کیا جا سکے کہ آیا منحصر ویجٹ کو دوبارہ تعمیر کرنے کی ضرورت ہے۔

کسٹم InheritedWidget بنانا

کسٹم InheritedWidget بنانے میں دو مراحل شامل ہیں: InheritedWidget کو بڑھانے والی کلاس کی تعریف کرنا، اور اولاد سے رسائی کے لیے ایک جامد of طریقہ کو نافذ کرنا۔ ڈیٹا کنسٹرکٹر کے ذریعے پاس کیا جاتا ہے، اور updateShouldNotify طریقہ تعین کرتا ہے کہ منحصر ویجٹ کو کب دوبارہ تعمیر ہونا چاہیے۔

مرحلہ 1: InheritedWidget کلاس کی تعریف

کلاس کو InheritedWidget بڑھانا چاہیے اور لازمی child پیرامیٹر کے ساتھ کنسٹرکٹر کے ذریعے ڈیٹا قبول کرنا چاہیے۔ ڈیٹا کسی بھی قسم کا ہو سکتا ہے: پریمیٹیو، آبجیکٹ، فنکشن۔ بنیادی اصول یہ ہے کہ ڈیٹا ناقابل تبدیلی (immutable) ہونا چاہیے تاکہ پرانی اور نئی اقدار کا قابل اعتبار طریقے سے موازنہ کیا جا سکے۔

مرحلہ 2: جامد of طریقہ

جامد of طریقہ BuildContext لیتا ہے اور InheritedWidget ڈیٹا لوٹاتا ہے۔ اندر، یہ dependOnInheritedWidgetOfExactType کو کال کرتا ہے، جو درخت میں مخصوص قسم کا قریب ترین InheritedWidget ڈھونڈتا ہے۔ اگر InheritedWidget نہیں ملتا، طریقہ نفاذ کے مطابق ایک استثناء پھینکتا ہے یا ڈیفالٹ ویلیو لوٹاتا ہے۔

مرحلہ 3: ویجٹ میں استعمال

ڈیٹا تک رسائی کے لیے، ویجٹ build طریقہ کے اندر MyWidget.of(context) کال کرتا ہے۔ Flutter خود بخود ویجٹ کو اپ ڈیٹس سبسکرائب کرتا ہے۔ اگر ڈیٹا تبدیل ہوتا ہے، ویجٹ اگلے فریم میں دوبارہ تعمیر ہوتا ہے۔ یہ غیر ضروری پیرامیٹرز کے بغیر صاف اور اعلانیہ کوڈ کی اجازت دیتا ہے۔

dart
class UserPreferences extends InheritedWidget {
  final String languageCode;
  final bool darkMode;

  const UserPreferences({
    required this.languageCode,
    required this.darkMode,
    required Widget child,
  }) : super(child: child);

  static UserPreferences of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<UserPreferences>()!;
  }

  @override
  bool updateShouldNotify(UserPreferences oldWidget) =>
    oldWidget.languageCode != languageCode || oldWidget.darkMode != darkMode;
}

اس مثال میں، UserPreferences صارف کی ترتیبات کو ذخیرہ کرتا ہے۔ updateShouldNotify طریقہ ہر فیلڈ کا انفرادی طور پر موازنہ کرتا ہے، جو صرف ایک پیرامیٹر تبدیل ہونے پر غیر ضروری دوبارہ تعمیر کو روکتا ہے۔ ایک سے زیادہ فیلڈ والے اپنے InheritedWidget کے لیے اسی طرح کا طریقہ استعمال کریں۔

updateShouldNotify طریقہ اور غیر ضروری دوبارہ تعمیر کو روکنا

updateShouldNotify InheritedWidget کا اہم طریقہ ہے جو تعین کرتا ہے کہ آیا منحصر ویجٹ کو ڈیٹا کی تبدیلیوں کے بارے میں مطلع کرنے کی ضرورت ہے۔ اگر طریقہ false لوٹاتا ہے، منحصر ویجٹ دوبارہ تعمیر نہیں ہوتے، چاہے InheritedWidget نے خود ایک ہی ڈیٹا کے ساتھ نیا انسٹنس حاصل کیا ہو۔ یہ کارکردگی کے لیے انتہائی اہم ہے۔

updateShouldNotify کا درست نفاذ

صرف ان فیلڈز کا موازنہ کریں جو واقعی تبدیل ہوئے ہیں اور ڈسپلے کو متاثر کرتے ہیں۔ اگر InheritedWidget میں 10 فیلڈز ہیں لیکن صرف ایک UI کو متاثر کرتا ہے، صرف اس فیلڈ کو چیک کریں۔ کلیکشنز کے لیے، گہرا موازنہ یا ناقابل تبدیلی ڈیٹا ڈھانچے استعمال کریں۔ List یا Map کے لیے == استعمال نہ کریں، کیونکہ وہ حوالہ سے موازنہ کرتے ہیں۔

  • پریمیٹیو — براہ راست موازنہ استعمال کریں: oldWidget.value != value.
  • ناقابل تبدیلی آبجیکٹ — اوور رائڈ شدہ == استعمال کریں: oldWidget.data != data (اگر data == کو اوور رائڈ کرتا ہے).
  • کلیکشنز — package:flutter/foundation.dart سے listEquals، mapEquals استعمال کریں.

updateShouldNotify نفاذ میں نقائص

سب سے عام غلطی موازنہ کے بغیر true لوٹانا ہے۔ اس کی وجہ سے تمام منحصر ویجٹ ہر پیرنٹ اپ ڈیٹ پر دوبارہ تعمیر ہوتے ہیں، چاہے ڈیٹا تبدیل نہ ہوا ہو۔ دوسری غلطی ڈیٹا تبدیل ہونے پر false لوٹانا ہے، جس سے UI پرانا ہو جاتا ہے۔ تیسری پیچیدہ موازنہ ہے جو ہر فریم چلتی ہے اور کام سست کر دیتی ہے۔

InheritedWidget بمقابلہ کال بیکس: کیا منتخب کریں؟

InheritedWidget اور کال بیکس (کنسٹرکٹرز کے ذریعے فنکشن پاس کرنا) مختلف مسائل حل کرتے ہیں۔ InheritedWidget اس ڈیٹا کے لیے موزوں ہے جس کی درخت کی مختلف سطحوں پر بہت سے ویجٹ کو ضرورت ہوتی ہے۔ کال بیکس پیرنٹ سے مخصوص چائلڈ تک یا اس کے برعکس یک طرفہ ایونٹ پاس کرنے کے لیے آسان ہیں۔ انتخاب ایپلیکیشن آرکیٹیکچر اور اپ ڈیٹ فریکوئنسی پر منحصر ہے۔

InheritedWidget کب استعمال کریں

InheritedWidget استعمال کریں جب مختلف nesting سطحوں پر بہت سے ویجٹ کو ڈیٹا کی ضرورت ہو: ایپ تھیم، صارف کی ترتیبات، ڈیوائس کی معلومات، موجودہ سیشن ڈیٹا۔ InheritedWidget خاص طور پر “عالمی” ڈیٹا کے لیے مؤثر ہے جو شاذ و نادر ہی تبدیل ہوتا ہے لیکن UI کے مختلف حصوں میں ضروری ہوتا ہے۔

کال بیکس کب استعمال کریں

کال بیکس (کال بیک فنکشنز) چائلڈ ویجٹ سے پیرنٹ تک ایونٹ پاس کرنے کے لیے موزوں ہیں: بٹن دبانا، فہرست آئٹم کا انتخاب، فارم جمع کرانا۔ کال بیکس واضح طور پر بتاتے ہیں کہ چائلڈ کون سے اقدامات کر سکتا ہے اور پوشیدہ انحصار نہیں بناتے۔ کم تعداد میں سطحوں پر درخت میں نیچے ڈیٹا پاس کرنے کے لیے، کنسٹرکٹر پیرامیٹرز استعمال کرنا بھی آسان ہے۔

معیارInheritedWidgetکال بیکس
سمتاوپر سے نیچے (پیرنٹ → اولاد)نیچے سے اوپر (چائلڈ → پیرنٹ) یا براہ راست
دائرہپورا سب ٹریمخصوص ویجٹ
دوبارہ تعمیرڈیٹا تبدیل ہونے پر خودکاردستی setState درکار
پیچیدگیدرمیانی (InheritedWidget کلاس درکار)کم (صرف ایک فنکشن)

InheritedWidget اور اسٹیٹ مینجمنٹ لائبریریاں

Provider اور Riverpod InheritedWidget کے اوپر بنائی گئی Flutter میں مشہور اسٹیٹ مینجمنٹ لائبریریاں ہیں۔ یہ اس کی صلاحیتوں کو بڑھاتے ہیں: ChangeNotifier سپورٹ، ان ماؤنٹ ہونے پر خودکار تصفیہ، سست آغاز، اور جنرکس کے ساتھ آسان نحو شامل کرتے ہیں۔

InheritedWidget پر مبنی Provider

Provider کسی بھی قسم کی شے کو درخت میں نیچے پاس کرنے کے لیے InheritedWidget استعمال کرتا ہے۔ ChangeNotifierProvider ChangeNotifier کے ذریعے تبدیلیوں کو ٹریک کرتا ہے اور notifyListeners کال ہونے پر updateShouldNotify کو کال کرتا ہے۔ یہ ڈویلپر کو دستی طور پر InheritedWidget بنانے اور updateShouldNotify نافذ کرنے سے آزاد کرتا ہے۔

براہ راست InheritedWidget سے موازنہ

براہ راست InheritedWidget زیادہ کنٹرول دیتا ہے اور بیرونی انحصار کی ضرورت نہیں ہوتی۔ Provider تیار بنیادی ڈھانچہ فراہم کرتا ہے: Consumer، Selector، MultiProvider، ProxyProvider۔ انتخاب ایپلیکیشن کی پیچیدگی پر منحصر ہے۔ سادہ پروجیکٹس کے لیے، براہ راست InheritedWidget کافی ہے؛ بڑے پروجیکٹس کے لیے، Provider یا Riverpod بوائلرپلیٹ کوڈ کم کرتے ہیں۔

dart
// براہ راست InheritedWidget
class UserProvider extends InheritedWidget {
  final UserData userData;
  const UserProvider({required this.userData, required Widget child}) : super(child: child);
  static UserData of(BuildContext context) => context.dependOnInheritedWidgetOfExactType<UserProvider>()!.userData;
  @override
  bool updateShouldNotify(UserProvider old) => old.userData != userData;
}

// Provider مساوی
return ChangeNotifierProvider<UserData>(
  create: (_) => UserData(),
  child: MyApp(),
);

مثال میں دونوں نقطہ نظر ایک ہی مسئلہ حل کرتے ہیں — UserData کو درخت میں نیچے پاس کرنا۔ Provider کوڈ کی مقدار کم کرتا ہے لیکن InheritedWidget کے میکانکس کو چھپاتا ہے۔ براہ راست InheritedWidget مکمل کنٹرول اور سمجھ فراہم کرتا ہے کہ کیا ہو رہا ہے، جو خاص طور پر Flutter سیکھنے اور پیچیدہ دوبارہ تعمیر کے مسائل کو ڈیبگ کرتے وقت اہم ہے۔

اکثر پوچھے گئے سوالات

InheritedWidget عام ویجٹ سے کیسے مختلف ہے؟

InheritedWidget BuildContext کے ذریعے تمام اولاد کے لیے ڈیٹا دستیاب کرتا ہے، جبکہ عام ویجٹ صرف کنسٹرکٹر کے ذریعے ڈیٹا پاس کرتا ہے۔ InheritedWidget اولاد کو ڈیٹا اپ ڈیٹس بھی سبسکرائب کرتا ہے۔

منحصر ویجٹ کتنی بار دوبارہ تعمیر ہوتے ہیں؟

منحصر ویجٹ صرف اس وقت دوبارہ تعمیر ہوتے ہیں جب updateShouldNotify true لوٹاتا ہے۔ اگر طریقہ درست طریقے سے نافذ کیا گیا ہے، دوبارہ تعمیر صرف اس وقت ہوتی ہے جب ڈیٹا حقیقت میں تبدیل ہوتا ہے، ہر پیرنٹ دوبارہ تعمیر پر نہیں۔

کیا ایک ہی درخت میں متعدد InheritedWidget استعمال کیے جا سکتے ہیں؟

ہاں، آپ ایک ہی درخت میں کسی بھی تعداد میں InheritedWidget استعمال کر سکتے ہیں۔ ہر ایک مخصوص قسم کا ڈیٹا فراہم کرتا ہے، اور ویجٹ ایک ساتھ متعدد InheritedWidget سے ڈیٹا حاصل کر سکتے ہیں۔

dependOnInheritedWidgetOfExactType اور findAncestorWidgetOfExactType میں کیا فرق ہے؟

dependOn ویجٹ کو اپ ڈیٹس سبسکرائب کرتا ہے — جب ڈیٹا تبدیل ہوتا ہے، ویجٹ دوبارہ تعمیر ہوتا ہے۔ findAncestor سبسکرپشن کے بغیر ایک بار کی تلاش کرتا ہے، اور ویجٹ ڈیٹا کی تبدیلیوں سے آگاہ نہیں ہوگا۔

کیا InheritedWidget پیچیدہ اسٹیٹ مینجمنٹ کے لیے موزوں ہے؟

سادہ حالت (تھیم، ترتیبات) کے لیے InheritedWidget کافی ہے۔ کاروباری منطق کے ساتھ پیچیدہ حالت کے لیے، Provider، Riverpod یا BLoC استعمال کریں — یہ InheritedWidget پر بنائے گئے ہیں اور ضروری بنیادی ڈھانچہ شامل کرتے ہیں۔

خلاصہ

  • InheritedWidget خودکار اپ ڈیٹ سبسکرپشن کے ساتھ درخت میں نیچے ڈیٹا پاس کرنے کے لیے Flutter کا ایک خاص ویجٹ ہے۔
  • کام کرنے کا طریقہ کار Element Tree پر مبنی: InheritedElement منحصر عناصر کو رجسٹر کرتا ہے اور انہیں تبدیلیوں سے آگاہ کرتا ہے۔
  • updateShouldNotify — منحصر ویجٹ کی غیر ضروری دوبارہ تعمیر کو روکنے کا اہم طریقہ۔
  • بلٹ ان InheritedWidget: Theme، MediaQuery، Localizations، Directionality، DefaultTextStyle۔
  • کسٹم بنانا میں کلاس انحصار، کنسٹرکٹر کے ذریعے ڈیٹا پاس کرنا اور ایک جامد of طریقہ شامل ہے۔
  • Provider اور Riverpod InheritedWidget کے اوپر بنائے گئے ہیں اور ChangeNotifier، Consumer، Selector اور آسان نحو شامل کرتے ہیں۔
  • InheritedWidget prop drilling مسئلہ حل کرتا ہے اور Flutter میں رد عمل اسٹیٹ مینجمنٹ کی بنیاد ہے۔

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں