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 का ट्री ट्रैवर्सल

जब कोई विजेट 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 का उपयोग करें जब डेटा की आवश्यकता विभिन्न नेस्टिंग स्तरों पर कई विजेट को हो: ऐप थीम, उपयोगकर्ता सेटिंग्स, डिवाइस जानकारी, वर्तमान सत्र डेटा। 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 एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें