InheritedWidget — nedir, ağaçta veri aktarımı ve nasıl çalışır

Yazar: IT Sectr Yayınlanma: 2026-07-02 Okuma süresi: 9 dk

InheritedWidget, Flutter'da yapıcılar aracılığıyla açıkça iletmeden widget ağacında aşağıya doğru veri aktaran özel bir widget'tır. Alt widget'lar BuildContext aracılığıyla verilere erişir ve otomatik olarak güncellemelere abone olur. InheritedWidget'daki veriler değiştiğinde, bağımlı tüm widget'lar yeniden oluşturulur. Flutter API Reference, 2025'e göre InheritedWidget, Theme, MediaQuery, Localizations ve çoğu durum yönetimi kütüphanesinin temelidir.

Önemli Noktalar

  • InheritedWidget, her widget üzerinden açıkça geçirmeden Widget Tree'de aşağıya doğru veri aktarır.
  • Otomatik abonelik — dependOnInheritedWidgetOfExactType kullanan widget'lar veri değiştiğinde yeniden oluşturulur.
  • Theme ve MediaQuery, her Flutter uygulamasında bulunan InheritedWidget'ın yerleşik örnekleridir.
  • Provider ve Riverpod, InheritedWidget üzerine inşa edilmiştir ve durum yönetimi için yeteneklerini genişletir.
  • Doğru uygulama, gereksiz yeniden oluşturmaları önlemek için updateShouldNotify'ı geçersiz kılmayı gerektirir.

Flutter'da InheritedWidget Nedir?

InheritedWidget, verilerini Widget Tree'deki tüm torunlar için kullanılabilir hale getiren bir widget'tır. Verileri yalnızca yapıcılar aracılığıyla alt öğelere aktaran normal bir widget'ın aksine, InheritedWidget, alt ağaçtaki herhangi bir widget'ın parametre zinciri olmadan verilere erişmesine izin verir. Bu, “prop drilling” sorununu çözer — bu verileri kendileri kullanmayan birçok ara widget üzerinden veri aktarma.

Yerleşik InheritedWidget'lar

Flutter birkaç yerleşik InheritedWidget içerir: Theme (renk şeması ve stiller), MediaQuery (ekran boyutu, yönlendirme, piksel yoğunluğu), Localizations (yerelleştirilmiş dizeler), Directionality (metin yönü), DefaultTextStyle (varsayılan metin stili). Bu widget'lar MaterialApp gibi kök widget'lar tarafından ayarlanır ve uygulama genelinde kullanılabilir.

InheritedWidget Yaşam Döngüsü

InheritedWidget'ın kendi durumu yoktur — yapıcı aracılığıyla aktarılan verileri depolar. InheritedWidget'ın ebeveyni yeni verilerle yeniden oluşturulduğunda, eski ve yeni verileri karşılaştırmak için updateShouldNotify yöntemi çağrılır. Yöntem true döndürürse, bağımlı tüm widget'lar yeniden oluşturma için işaretlenir. Bu basit ama etkili bir reaktif güncelleme mekanizmasıdır.

InheritedWidget Üzerinden Veri Aktarımı Nasıl Çalışır

InheritedWidget üzerinden veri aktarım mekanizması Element Tree'ye dayanır. Bir widget dependOnInheritedWidgetOfExactType'ı çağırdığında, ilgili öğe InheritedElement üzerinde bir bağımlılık kaydeder. InheritedWidget değiştiğinde, InheritedElement bağımlı tüm öğeleri bildirir ve bunlar sonraki karede yeniden oluşturulur.

Bağımlılık Kaydı

dependOnInheritedWidgetOfExactType yöntemi yalnızca ağaçta InheritedWidget'ı bulmakla kalmaz — geçerli öğeyi bildirimlere abone yapar. dependOn yerine findAncestorWidgetOfExactType kullanırsanız, widget verileri alır ancak değiştiğinde yeniden oluşturulmaz. Bu önemli bir farktır: dependOn bir aboneliktir, findAncestor tek seferlik bir aramadır.

InheritedWidget Ağaç Geçişi

Bir widget InheritedWidget istediğinde, Flutter geçerli öğeden köke kadar Element Tree'de yukarı çıkar ve her InheritedElement'i tür eşleşmesi için kontrol eder. Eşleşen ilk InheritedElement döndürülür. Bu, ağaçtaki en yakın InheritedWidget'ın önceliğe sahip olduğu anlamına gelir — InheritedWidget'ı torunlara daha yakın yerleştirerek belirli bir seviyede verileri geçersiz kılabilirsiniz.

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 örnekte, MyTheme torunlara veri sağlamak için statik bir of yöntemi kullanır. dependOnInheritedWidgetOfExactType yöntemi bir bağımlılık kaydeder ve updateShouldNotify, bağımlı widget'ların yeniden oluşturulması gerekip gerekmediğini belirlemek için eski ve yeni verileri karşılaştırır.

Özel InheritedWidget Oluşturma

Özel InheritedWidget oluşturma iki adımdan oluşur: InheritedWidget'ı genişleten bir sınıf tanımlama ve torunlardan erişim için statik bir of yöntemi uygulama. Veriler yapıcı aracılığıyla aktarılır ve updateShouldNotify yöntemi, bağımlı widget'ların ne zaman yeniden oluşturulması gerektiğini belirler.

Adım 1: InheritedWidget Sınıfını Tanımlama

Sınıf InheritedWidget'ı genişletmeli ve zorunlu child parametresi olan bir yapıcı aracılığıyla verileri kabul etmelidir. Veriler herhangi bir türde olabilir: ilkeller, nesneler, işlevler. Ana kural, eski ve yeni değerlerin güvenilir bir şekilde karşılaştırılabilmesi için verilerin değişmez (immutable) olması gerektiğidir.

Adım 2: Statik of Yöntemi

Statik of yöntemi BuildContext alır ve InheritedWidget verilerini döndürür. İçte, ağaçta belirtilen türdeki en yakın InheritedWidget'ı bulan dependOnInheritedWidgetOfExactType'ı çağırır. InheritedWidget bulunamazsa, yöntem uygulamaya bağlı olarak bir istisna fırlatır veya varsayılan bir değer döndürür.

Adım 3: Widget'larda Kullanım

Verilere erişmek için widget, build yöntemi içinde MyWidget.of(context) çağrısı yapar. Flutter otomatik olarak widget'ı güncellemelere abone yapar. Veriler değişirse, widget sonraki karede yeniden oluşturulur. Bu, gereksiz parametreler olmadan temiz ve bildirimsel kod sağlar.

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 örnekte, UserPreferences kullanıcı ayarlarını saklar. updateShouldNotify yöntemi her alanı ayrı ayrı karşılaştırır, bu da yalnızca bir parametre değiştiğinde gereksiz yeniden oluşturmaları önler. Birden çok alanı olan kendi InheritedWidget'larınız için benzer bir yaklaşım kullanın.

updateShouldNotify Yöntemi ve Gereksiz Yeniden Oluşturmaları Önleme

updateShouldNotify, bağımlı widget'ların veri değişiklikleri hakkında bilgilendirilmesi gerekip gerekmediğini belirleyen InheritedWidget'ın ana yöntemidir. Yöntem false döndürürse, InheritedWidget'ın kendisi aynı verilerle yeni bir örnek alsa bile bağımlı widget'lar yeniden oluşturulmaz. Bu, performans için kritik derecede önemlidir.

updateShouldNotify'ın Doğru Uygulanması

Yalnızca gerçekten değişen ve görüntülemeyi etkileyen alanları karşılaştırın. InheritedWidget 10 alan içeriyorsa ancak yalnızca biri kullanıcı arayüzünü etkiliyorsa, yalnızca o alanı kontrol edin. Koleksiyonlar için derin karşılaştırma veya değişmez veri yapıları kullanın. Liste veya Harita için == kullanmayın, çünkü referansa göre karşılaştırma yaparlar.

  • İlkeller — doğrudan karşılaştırma kullanın: oldWidget.value != value.
  • Değişmez nesneler — geçersiz kılınmış == kullanın: oldWidget.data != data (data == geçersiz kılıyorsa).
  • Koleksiyonlar — package:flutter/foundation.dart'den listEquals, mapEquals kullanın.

updateShouldNotify Uygulamasında Hatalar

En yaygın hata, karşılaştırma olmadan true döndürmektir. Bu, veriler değişmemiş olsa bile tüm bağımlı widget'ların her ebeveyn güncellemesinde yeniden oluşturulmasına neden olur. İkinci hata, veriler değiştiğinde false döndürmektir, bu da güncel olmayan bir kullanıcı arayüzüne yol açar. Üçüncüsü, her karede çalışan ve performansı yavaşlatan karmaşık karşılaştırmadır.

InheritedWidget vs Geri Çağrımlar: Hangisi Seçilmeli?

InheritedWidget ve geri çağrımlar (yapıcılar aracılığıyla işlev aktarma) farklı sorunları çözer. InheritedWidget, ağacın farklı seviyelerinde birçok widget tarafından ihtiyaç duyulan veriler için uygundur. Geri çağrımlar, ebeveynden belirli bir alt öğeye veya tam tersi yönde tek yönlü olay aktarımı için kullanışlıdır. Seçim, uygulama mimarisine ve güncelleme sıklığına bağlıdır.

InheritedWidget Ne Zaman Kullanılır

Farklı iç içe geçme seviyelerinde birçok widget tarafından veriye ihtiyaç duyulduğunda InheritedWidget kullanın: uygulama teması, kullanıcı ayarları, cihaz bilgileri, mevcut oturum verileri. InheritedWidget özellikle nadiren değişen ancak kullanıcı arayüzünün farklı bölümlerinde ihtiyaç duyulan “küresel” veriler için etkilidir.

Geri Çağrımlar Ne Zaman Kullanılır

Geri çağrımlar (callback işlevleri), bir alt widget'tan ebeveyne olay aktarmak için uygundur: düğmeye basma, liste öğesi seçimi, form gönderme. Geri çağrımlar, bir alt öğenin hangi eylemleri gerçekleştirebileceğini açıkça belirtir ve gizli bağımlılıklar oluşturmaz. Az sayıda seviye üzerinden ağaçta aşağıya doğru veri aktarmak için yapıcı parametrelerini kullanmak da daha basittir.

KriterInheritedWidgetGeri Çağrımlar
YönYukarıdan aşağıya (ebeveyn → torunlar)Aşağıdan yukarıya (alt → ebeveyn) veya doğrudan
KapsamTüm alt ağaçBelirli widget
Yeniden OluşturmaVeri değişiminde otomatikManuel setState gerektirir
KarmaşıklıkOrta (InheritedWidget sınıfı gerekir)Düşük (sadece bir işlev)

InheritedWidget ve Durum Yönetimi Kütüphaneleri

Provider ve Riverpod, InheritedWidget üzerine inşa edilmiş Flutter'daki popüler durum yönetimi kütüphaneleridir. Yeteneklerini genişletirler: ChangeNotifier desteği, çıkarma sırasında otomatik temizleme, tembel başlatma ve jeneriklerle basitleştirilmiş sözdizimi eklerler.

InheritedWidget Tabanlı Provider

Provider, herhangi bir türdeki nesneyi ağaçta aşağıya aktarmak için InheritedWidget kullanır. ChangeNotifierProvider, ChangeNotifier aracılığıyla değişiklikleri izler ve notifyListeners çağrıldığında updateShouldNotify'ı çağırır. Bu, geliştiriciyi manuel olarak InheritedWidget oluşturmaktan ve updateShouldNotify uygulamaktan kurtarır.

Doğrudan InheritedWidget ile Karşılaştırma

Doğrudan InheritedWidget daha fazla kontrol sağlar ve harici bağımlılıklar gerektirmez. Provider hazır altyapı sağlar: Consumer, Selector, MultiProvider, ProxyProvider. Seçim, uygulama karmaşıklığına bağlıdır. Basit projeler için doğrudan InheritedWidget yeterlidir; büyük projeler için Provider veya Riverpod kalıplaşmış kodu azaltır.

dart
// Doğrudan 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 eşdeğeri
return ChangeNotifierProvider<UserData>(
  create: (_) => UserData(),
  child: MyApp(),
);

Örnekteki her iki yaklaşım da aynı sorunu çözer — UserData'yı ağaçta aşağıya aktarma. Provider kod hacmini azaltır ancak InheritedWidget mekaniğini gizler. Doğrudan InheritedWidget tam kontrol ve neler olup bittiğini anlama sağlar, bu özellikle Flutter öğrenirken ve karmaşık yeniden oluşturma sorunlarını hata ayıklarken önemlidir.

Sıkça Sorulan Sorular

InheritedWidget normal bir widget'tan nasıl farklıdır?

InheritedWidget BuildContext aracılığıyla tüm torunlar için verileri kullanılabilir hale getirirken, normal bir widget yalnızca yapıcı aracılığıyla veri aktarır. InheritedWidget ayrıca torunları veri güncellemelerine abone yapar.

Bağımlı widget'lar ne sıklıkla yeniden oluşturulur?

Bağımlı widget'lar yalnızca updateShouldNotify true döndürdüğünde yeniden oluşturulur. Yöntem doğru uygulanırsa, yeniden oluşturma yalnızca veriler gerçekten değiştiğinde gerçekleşir, her ebeveyn yeniden oluşturmasında değil.

Aynı ağaçta birden çok InheritedWidget kullanılabilir mi?

Evet, aynı ağaçta herhangi bir sayıda InheritedWidget kullanabilirsiniz. Her biri belirli bir türde veri sağlar ve widget'lar aynı anda birden çok InheritedWidget'dan veri alabilir.

dependOnInheritedWidgetOfExactType ve findAncestorWidgetOfExactType arasındaki fark nedir?

dependOn widget'ı güncellemelere abone yapar — veri değiştiğinde widget yeniden oluşturulur. findAncestor abonelik olmadan tek seferlik arama yapar ve widget veri değişikliklerinden haberdar olmaz.

InheritedWidget karmaşık durum yönetimi için uygun mudur?

Basit durum (tema, ayarlar) için InheritedWidget yeterlidir. İş mantığı olan karmaşık durum için Provider, Riverpod veya BLoC kullanın — bunlar InheritedWidget üzerine inşa edilmiştir ve gerekli altyapıyı ekler.

Özet

  • InheritedWidget, otomatik güncelleme aboneliği ile ağaçta aşağıya doğru veri aktarmak için Flutter'ın özel bir widget'ıdır.
  • Çalışma mekanizması Element Tree'ye dayanır: InheritedElement bağımlı öğeleri kaydeder ve onları değişikliklerden haberdar eder.
  • updateShouldNotify — bağımlı widget'ların gereksiz yeniden oluşturulmasını önlemek için ana yöntem.
  • Yerleşik InheritedWidget'lar: Theme, MediaQuery, Localizations, Directionality, DefaultTextStyle.
  • Özel oluşturma sınıf kalıtımı, yapıcı aracılığıyla veri aktarımı ve statik bir of yöntemi içerir.
  • Provider ve Riverpod InheritedWidget üzerine inşa edilmiştir ve ChangeNotifier, Consumer, Selector ve basitleştirilmiş sözdizimi ekler.
  • InheritedWidget prop drilling sorununu çözer ve Flutter'da reaktif durum yönetiminin temelidir.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun