InheritedWidget — bu nima, daraxtda ma'lumot uzatish va qanday ishlaydi

Muallif: IT Sectr Nashr etilgan: 2026-07-02 O'qish vaqti: 9 daq

InheritedWidget — bu Flutter-da konstruktorlar orqali aniq uzatmasdan vidjetlar daraxtidan pastga ma'lumot uzatuvchi maxsus vidjetdir. Farzand vidjetlar BuildContext orqali ma'lumotlarga kirishadi va avtomatik ravishda yangilanishlarga obuna bo'ladi. InheritedWidget-dagi ma'lumotlar o'zgarganda, barcha bog'liq vidjetlar qayta quriladi. Flutter API Reference, 2025 ma'lumotlariga ko'ra, InheritedWidget Theme, MediaQuery, Localizations va holat boshqaruv kutubxonalarining aksariyatining asosini tashkil qiladi.

Asosiy fikrlar

  • InheritedWidget har bir vidjet orqali aniq o'tkazmasdan Widget Tree bo'ylab ma'lumotni pastga uzatadi.
  • Avtomatik obuna — dependOnInheritedWidgetOfExactType ishlatadigan vidjetlar ma'lumot o'zgarganda qayta quriladi.
  • Theme va MediaQuery — har bir Flutter ilovasida mavjud bo'lgan o'rnatilgan InheritedWidget misollari.
  • Provider va Riverpod InheritedWidget asosida qurilgan va uning holat boshqaruv imkoniyatlarini kengaytiradi.
  • To'g'ri tatbiq keraksiz qayta qurilishlarning oldini olish uchun updateShouldNotify-ni qayta belgilashni talab qiladi.

Flutter-da InheritedWidget nima?

InheritedWidget — bu Widget Tree-da o'z ma'lumotlarini barcha avlodlarga mavjud qiladigan vidjetdir. Oddiy vidjetdan farqli o'laroq, ma'lumotlarni faqat konstruktor orqali farzand elementlarga uzatadigan InheritedWidget, pastki daraxtdagi istalgan vidjetga parametr zanjirisiz ma'lumotlarga kirish imkonini beradi. Bu "prop drilling" muammosini hal qiladi — bu ma'lumotlardan o'zlari foydalanmaydigan ko'plab oraliq vidjetlar orqali ma'lumot uzatish.

O'rnatilgan InheritedWidget

Flutter bir nechta o'rnatilgan InheritedWidget-ni o'z ichiga oladi: Theme (rang sxemasi va stillar), MediaQuery (ekran o'lchami, orientatsiya, piksel zichligi), Localizations (mahalliylashtirilgan satrlar), Directionality (matn yo'nalishi), DefaultTextStyle (standart matn uslubi). Bu vidjetlar MaterialApp kabi ildiz vidjetlar tomonidan o'rnatiladi va butun ilovada mavjud.

InheritedWidget ning hayot aylanishi

InheritedWidget o'z holatiga ega emas — konstruktor orqali uzatilgan ma'lumotlarni saqlaydi. InheritedWidget-ning ota-onasi yangi ma'lumotlar bilan qayta qurilganda, eski va yangi ma'lumotlarni solishtirish uchun updateShouldNotify metodi chaqiriladi. Agar metod true qaytarsa, barcha bog'liq vidjetlar qayta qurish uchun belgilanadi. Bu reaktiv yangilanishning sodda, ammo samarali mexanizmidir.

InheritedWidget orqali ma'lumot uzatish qanday ishlaydi

Ma'lumot uzatish mexanizmi InheritedWidget orqali Element Tree-ga asoslanadi. Vidjet dependOnInheritedWidgetOfExactType-ni chaqirganda, tegishli element InheritedElement-dan bog'liqlikni ro'yxatdan o'tkazadi. InheritedWidget o'zgarganda, InheritedElement barcha bog'liq elementlarni xabardor qiladi va ular keyingi kadrda qayta quriladi.

Bog'liqlikni ro'yxatdan o'tkazish

dependOnInheritedWidgetOfExactType metodi nafaqat daraxtda InheritedWidget-ni topadi — u joriy elementni bildirishnomalarga obuna qiladi. Agar dependOn o'rniga findAncestorWidgetOfExactType ishlatganingizda, vidjet ma'lumotlarni olar edi, lekin ular o'zgarganda qayta qurilmas edi. Bu muhim farq: dependOn — obuna, findAncestor — bir martalik qidiruv.

InheritedWidget daraxtida yurish

Vidjet InheritedWidget-ni so'raganda, Flutter joriy elementdan ildizgacha Element Tree bo'ylab ko'tariladi, har bir InheritedElement-ni tur mosligi uchun tekshiradi. Birinchi topilgan InheritedElement qaytariladi. Bu daraxtdagi eng yaqin InheritedWidget ustunlikka ega degani — InheritedWidget-ni avlodlarga yaqinroq joylashtirib, ma'lum bir darajadagi ma'lumotlarni bekor qilishingiz mumkin.

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;
}

Bu misolda MyTheme avlodlarga ma'lumot taqdim etish uchun statik of metodidan foydalanadi. dependOnInheritedWidgetOfExactType metodi bog'liqlikni ro'yxatdan o'tkazadi, updateShouldNotify esa bog'liq vidjetlarning qayta qurilish zaruriyatini aniqlash uchun eski va yangi ma'lumotlarni solishtiradi.

O'z InheritedWidget-ingizni yaratish

O'z InheritedWidget-ingizni yaratish ikki qadamdan iborat: InheritedWidget-dan meros oladigan sinfni aniqlash va avlodlardan kirish uchun statik of metodini tatbiq qilish. Ma'lumotlar konstruktor orqali uzatiladi, updateShouldNotify metodi esa bog'liq vidjetlarning qachon qayta qurilishi kerakligini aniqlaydi.

1-qadam: InheritedWidget sinfini aniqlash

Sinf InheritedWidget-dan meros olishi va majburiy child parametri bilan konstruktor orqali ma'lumotlarni qabul qilishi kerak. Ma'lumotlar istalgan turda bo'lishi mumkin: primitivlar, ob'ektlar, funksiyalar. Asosiy qoida — ma'lumotlar o'zgarmas (immutable) bo'lishi kerak, shunda eski va yangi qiymatlarni ishonchli solishtirish mumkin.

2-qadam: Statik of metodi

Statik of metodi BuildContext qabul qiladi va InheritedWidget ma'lumotlarini qaytaradi. Ichkarida daraxtda belgilangan turdagi eng yaqin InheritedWidget-ni qidiradigan dependOnInheritedWidgetOfExactType chaqiriladi. Agar InheritedWidget topilmasa, metod tatbiqqa qarab istisno tashlaydi yoki standart qiymat qaytaradi.

3-qadam: Vidjetlarda foydalanish

Ma'lumotlarga kirish uchun vidjet build metodi ichida MyWidget.of(context)-ni chaqiradi. Flutter avtomatik ravishda vidjetni yangilanishlarga obuna qiladi. Agar ma'lumotlar o'zgarsa, vidjet keyingi kadrda qayta quriladi. Bu keraksiz parametrlarsiz toza va deklarativ kod yaratishga imkon beradi.

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;
}

Bu misolda UserPreferences foydalanuvchi sozlamalarini saqlaydi. updateShouldNotify metodi har bir maydonni alohida solishtiradi, bu faqat bitta parametr o'zgarganda keraksiz qayta qurilishlarning oldini oladi. Bir nechta maydonli o'z InheritedWidget-ingiz uchun shunday yondashuvdan foydalaning.

updateShouldNotify metodi va keraksiz qayta qurilishlarning oldini olish

updateShouldNotify — ma'lumotlar o'zgarishi haqida bog'liq vidjetlarni xabardor qilish kerakligini aniqlaydigan InheritedWidget-ning asosiy metodidir. Agar metod false qaytarsa, bog'liq vidjetlar, hatto InheritedWidget bir xil ma'lumotlar bilan yangi nusxa olgan bo'lsa ham, qayta qurilmaydi. Bu ishlash uchun juda muhim.

updateShouldNotify-ni to'g'ri tatbiq qilish

Faqat haqiqatan o'zgargan va ko'rinishga ta'sir qiladigan maydonlarni solishtiring. Agar InheritedWidget 10 ta maydonni o'z ichiga olsa, lekin ulardan faqat bittasi UI-ga ta'sir qilsa, faqat shu maydonni tekshiring. To'plamlar uchun chuqur solishtirish yoki o'zgarmas ma'lumot tuzilmalaridan foydalaning. List yoki Map uchun == ishlatmang, chunki ular havola orqali solishtiriladi.

  • Primitivlar — to'g'ridan-to'g'ri solishtirishdan foydalaning: oldWidget.value != value.
  • O'zgarmas ob'ektlar — qayta belgilangan == dan foydalaning: oldWidget.data != data (agar data == ni qayta belgilasa).
  • To'plamlar — package:flutter/foundation.dart dan listEquals, mapEquals dan foydalaning.

updateShouldNotify tatbiqidagi xatolar

Eng keng tarqalgan xato — solishtirishsiz true qaytarish. Bu ma'lumotlar o'zgarmagan bo'lsa ham, ota-onaning har bir yangilanishida barcha bog'liq vidjetlarning qayta qurilishiga olib keladi. Ikkinchi xato — ma'lumotlar o'zgarganda false qaytarish, bu eskirgan UI-ga sabab bo'ladi. Uchinchisi — har bir kadrda bajariladigan va ishni sekinlashtiradigan murakkab solishtirish.

InheritedWidget vs callbacklar: nimani tanlash kerak?

InheritedWidget va callbacklar (funksiyalarni konstruktor orqali uzatish) turli vazifalarni hal qiladi. InheritedWidget daraxtning turli darajalarida ko'plab vidjetlarga kerak bo'lgan ma'lumotlar uchun mos keladi. Callbacklar hodisalarni ota-onadan ma'lum bir farzandga yoki aksincha bir yo'nalishli uzatish uchun qulaydir. Tanlov ilova arxitekturasi va o'zgarishlar chastotasiga bog'liq.

InheritedWidget qachon ishlatiladi

InheritedWidget-dan ma'lumotlar ko'plab vidjetlarga turli joylashtirish darajalarida kerak bo'lganda foydalaning: ilova mavzusi, foydalanuvchi sozlamalari, qurilma ma'lumotlari, joriy sessiya ma'lumotlari. InheritedWidget, ayniqsa, kamdan-kam o'zgaradigan, lekin UI ning turli qismlarida kerak bo'lgan "global" ma'lumotlar uchun samarali.

Callbacklar qachon ishlatiladi

Callbacklar (qaytarish funksiyalari) hodisalarni farzand vidjetdan ota-onaga uzatish uchun mos keladi: tugmani bosish, ro'yxat elementini tanlash, formani yuborish. Callbacklar farzand qanday harakatlarni bajarishi mumkinligini aniq ko'rsatadi va yashirin bog'liqliklarni yaratmaydi. Daraxtdan pastga oz sonli darajalar uchun ma'lumot uzatishda konstruktor parametrlaridan foydalanish ham soddaroq.

MezonInheritedWidgetCallbacklar
Yo'nalishYuqoridan pastga (ota-ona → avlodlar)Pastdan yuqoriga (farzand → ota-ona) yoki to'g'ridan-to'g'ri
QamrovButun pastki daraxtMuayyan vidjet
Qayta qurishMa'lumot o'zgarganda avtomatikQo'lda setState talab qiladi
MurakkablikO'rtacha (InheritedWidget sinfi kerak)Past (oddiy funksiya)

InheritedWidget va holat boshqaruv kutubxonalari

Provider va Riverpod — InheritedWidget asosida qurilgan Flutter-dagi mashhur holat boshqaruv kutubxonalari. Ular uning imkoniyatlarini kengaytiradi: ChangeNotifier qo'llab-quvvatlashi, demontajda avtomatik o'chirish, kechiktirilgan ishga tushirish va generiklar orqali soddalashtirilgan sintaksis qo'shadi.

InheritedWidget asosidagi Provider

Provider istalgan turdagi ob'ektni daraxtdan pastga uzatish uchun InheritedWidget-dan foydalanadi. ChangeNotifierProvider ChangeNotifier orqali o'zgarishlarni kuzatadi va notifyListeners chaqirilganda updateShouldNotify-ni chaqiradi. Bu dasturchini qo'lda InheritedWidget yaratish va updateShouldNotify tatbiq qilishdan ozod qiladi.

To'g'ridan-to'g'ri InheritedWidget bilan solishtirish

To'g'ridan-to'g'ri InheritedWidget ko'proq nazorat beradi va tashqi bog'liqliklarni talab qilmaydi. Provider tayyor infratuzilmani taqdim etadi: Consumer, Selector, MultiProvider, ProxyProvider. Tanlov ilovaning murakkabligiga bog'liq. Oddiy loyihalar uchun to'g'ridan-to'g'ri InheritedWidget yetarli, katta loyihalar uchun Provider yoki Riverpod shablon kodini kamaytiradi.

dart
// To'g'ridan-to'g'ri 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 ekvivalenti
return ChangeNotifierProvider<UserData>(
  create: (_) => UserData(),
  child: MyApp(),
);

Misoldagi ikkala yondashuv bir xil vazifani hal qiladi — UserData-ni daraxtdan pastga uzatish. Provider kod miqdorini kamaytiradi, lekin InheritedWidget mexanikasini yashiradi. To'g'ridan-to'g'ri InheritedWidget to'liq nazorat va sodir bo'layotgan voqealarni tushunishni ta'minlaydi, bu ayniqsa Flutter-ni o'rganishda va qayta qurish bilan bog'liq murakkab muammolarni bartaraf etishda muhim.

Tez-tez so'raladigan savollar

InheritedWidget oddiy vidjetdan qanday farq qiladi?

InheritedWidget ma'lumotlarni BuildContext orqali barcha avlodlarga mavjud qiladi, oddiy vidjet esa ma'lumotlarni faqat konstruktor orqali uzatadi. InheritedWidget shuningdek avlodlarni ma'lumot yangilanishlariga obuna qiladi.

Bog'liq vidjetlar qanchalik tez-tez qayta quriladi?

Bog'liq vidjetlar faqat updateShouldNotify true qaytarganda qayta quriladi. Agar metod to'g'ri tatbiq qilingan bo'lsa, qayta qurish faqat ma'lumotlar haqiqatan o'zgarganda sodir bo'ladi, ota-onaning har bir rebuild-idagina emas.

Bitta daraxtda bir nechta InheritedWidget ishlatish mumkinmi?

Ha, bitta daraxtda istalgan miqdorda InheritedWidget ishlatish mumkin. Har biri ma'lum bir turdagi ma'lumotlarni taqdim etadi, vidjetlar esa bir vaqtning o'zida bir nechta InheritedWidget-dan ma'lumot olishi mumkin.

dependOnInheritedWidgetOfExactType findAncestorWidgetOfExactType-dan qanday farq qiladi?

dependOn vidjetni yangilanishlarga obuna qiladi — ma'lumot o'zgarganda vidjet qayta quriladi. findAncestor obunasiz bir martalik qidiruvni amalga oshiradi va vidjet ma'lumot o'zgarishlaridan xabardor bo'lmaydi.

InheritedWidget murakkab holatni boshqarish uchun mosmi?

Oddiy holat (mavzu, sozlamalar) uchun InheritedWidget yetarli. Biznes mantiqi bilan murakkab holat uchun Provider, Riverpod yoki BLoC dan foydalaning — ular InheritedWidget asosida qurilgan va kerakli infratuzilmani qo'shadi.

Xulosa

  • InheritedWidget — avtomatik yangilanish obunasi bilan daraxtdan pastga ma'lumot uzatish uchun maxsus Flutter vidjeti.
  • Ish mexanizmi Element Tree-ga asoslanadi: InheritedElement bog'liq elementlarni ro'yxatdan o'tkazadi va ularni o'zgarishlar haqida xabardor qiladi.
  • updateShouldNotify — bog'liq vidjetlarning keraksiz qayta qurilishining oldini olish uchun asosiy metod.
  • O'rnatilgan InheritedWidget: Theme, MediaQuery, Localizations, Directionality, DefaultTextStyle.
  • O'z InheritedWidget-ingizni yaratish sinfdan meros olishni, konstruktor orqali ma'lumot uzatishni va statik of metodini o'z ichiga oladi.
  • Provider va Riverpod InheritedWidget asosida qurilgan va ChangeNotifier, Consumer, Selector hamda soddalashtirilgan sintaksis qo'shadi.
  • InheritedWidget prop drilling muammosini hal qiladi va Flutter-da reaktiv holat boshqaruvining asosini tashkil qiladi.

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing