BuildContext — nedir, temel kavramlar ve çalışma prensibi

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

BuildContext, öğe ağacında belirli bir widget’ın konumunu temsil eden ve çevresine erişim sağlayan temel bir Flutter nesnesidir. Resmi Flutter belgelerine (Flutter.dev, 2026) göre BuildContext, widget ile framework arasında bir köprü görevi görür: bu sayede widget, temayı (Theme), medya sorgularını (MediaQuery), yerelleştirmeyi (Localizations) ve InheritedWidget’dan verileri alır. Her widget’ın, build yöntemine ilk argüman olarak iletilen kendi BuildContext’i vardır.

Önemli Noktalar

  • BuildContext — öğe ağacında widget’ın konumunu temsil eden ve hiyerarşik çevresine erişim sağlayan bir nesne
  • InheritedWidget — ağaçta aşağıya doğru veri göndermek için ana mekanizma, BuildContext üzerinden erişilir
  • of() yöntemi — ağaçta yukarı doğru en yakın InheritedWidget’ı bulmak için BuildContext kullanan statik bir yöntem (Theme.of, MediaQuery.of)
  • Bağlam ve yaşam döngüsü — widget taşındığında BuildContext değişir; dispose’tan sonra bağlam referansı saklanamaz
  • Hatalar — BuildContext’i ağacının dışında veya dispose’tan sonra kullanmak istisnalara yol açar (sıcak yeniden yüklemeler, async callback’ler)

BuildContext Nedir?

BuildContext, Element sınıfı tarafından uygulanan ve bir widget’a UI hiyerarşisindeki konumu hakkında bilgi sağlayan bir arayüzdür. Her BuildContext örneği, ağaçtaki belirli bir konum için benzersizdir ve başka bir yere taşınamaz. Bir widget ebeveynini değiştirirse (örneğin başka bir kapsayıcıya taşınırsa), yeni bir BuildContext alır.

BuildContext’in ana amacı InheritedWidget’a erişim sağlamaktır. Bağlam aracılığıyla bir widget, ağaçta yukarı doğru ilerleyerek en yakın Theme, MediaQuery, Navigator veya Directionality örneğini bulur. Bu mekanizma, Flutter’daki tema, navigasyon ve uyarlanabilir düzen sisteminin temelini oluşturur. BuildContext olmadan hiçbir widget bu verilere erişemez.

Flutter mimari belgelerine (Google, 2026) göre BuildContext, boyutları ölçmek ve konumlandırma için bir widget’la ilişkili RenderObject’u bulmak için de kullanılır. findRenderObject() ve size gibi yöntemler bağlam üzerinden kullanılabilir. Bağlam ayrıca Localizations.of(context) aracılığıyla yerelleştirmeye erişim sağlar.

BuildContext Bir Element’tir, Widget Değil

Önemli bir mimari anlayış: BuildContext, Element tarafından uygulanan bir arayüzdür, Widget tarafından değil. Element, Widget (yapılandırma) ile RenderObject (gerçek görüntüleme) arasındaki “yapıştırıcıdır”. Belgeler “widget bağlamı” dediğinde, bu widget’ı yöneten öğeyi kasteder. build yöntemi tam olarak bu tür bir bağlam alır — oluşturulmakta olan widget’ın bağlamı, döndürdüğü alt widget’ların değil.

BuildContext Nasıl Çalışır?

BuildContext mekanizması, öğe ağacını aşağıdan yukarıya doğru geçmeye dayanır. Bir widget Theme.of(context) çağırdığında, bağlam geçerli öğeden aramaya başlar ve köke doğru yukarı hareket ederek her öğeyi Theme türünde bir InheritedWidget için kontrol eder. Bulunan ilk InheritedWidget döndürülür — bu, widget’ın temayı en yakın tanımdan almasını garanti eder.

Her BuildContext, ebeveyn bağlama (parent) ve alt bağlamlara bir referans depolar. Bu, ağaçta hem yukarı (ebeveynlere) hem de aşağı (çocuklara) doğru gezinmeye izin veren çift yönlü bir bağlantıdır. Flutter’da InheritedWidget araması yalnızca yukarı doğru gezinmeyi kullanır — bir widget yalnızca atalarından veri alabilir, torunlarından alamaz. Bu temel bir mimari kısıtlamadır.

Flutter kaynak koduna (Flutter SDK, 2026) göre BuildContext şu yöntemleri içerir: visitAncestorElements, visitChildElements, findAncestorWidgetOfExactType, dependOnInheritedWidgetOfExactType ve getRenderObject. Son ikisi en çok kullanılanlardır: dependOnInheritedWidgetOfExactType yalnızca InheritedWidget’ı bulmakla kalmaz, aynı zamanda değişikliklerine abone olur (InheritedWidget değiştiğinde widget yeniden oluşturulur).

Bağlam Üzerinden Abonelik

dependOnInheritedWidgetOfExactType, tepkiselliği sağlayan BuildContext’in anahtar yöntemidir. Bir widget Theme.of(context) çağırdığında, yalnızca temayı almakla kalmaz — aynı zamanda değişikliklerine abone olur. Theme değişirse (örneğin karanlık/aydınlık mod arasında geçiş yaparken), abone olan tüm widget’lar otomatik olarak yeniden oluşturulur. Flutter’daki tepkisellik mekanizması budur.

BuildContext vs Element

BuildContext bir arayüzdür, Element ise onun uygulamasıdır. Flutter kodunda, belirli öğe türünü (StatelessElement, StatefulElement, ProxyElement vb.) bilmeden her zaman BuildContext arayüzü üzerinden çalışırsın. Bu kasıtlıdır: geliştiricinin öğenin uygulama detaylarını bilmesi gerekmez — çevreye erişmek için arayüz yeterlidir.

Farklı öğe türleri BuildContext’i farklı şekillerde uygular: StatelessElement build çağrılarını basitçe iletir, StatefulElement State’i yönetir ve InheritedElement, dependOnInheritedWidgetOfExactType aracılığıyla abonelikleri takip eder. Ancak geliştirici açısından bakıldığında, hepsi birleşik bir API ile BuildContext’tir.

YönBuildContextElement
TürArayüz (soyut sınıf)Uygulama sınıfı
KullanımGeliştirici tarafından build’deFlutter iç mekanizması
Arama yöntemleriof(), findAncestor...()mount, update, unmount
Kamuya açıklıkKamuya açık APIPaket içi
Widget ilişkisiwidget alanı aracılığıylawidget ve state’e sahiptir

Dart Kod Örnekleri

Temaya ve medya sorgularına erişmek için BuildContext’in temel kullanımı:

dart
class ThemedText extends StatelessWidget {
  const ThemedText({super.key});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final media = MediaQuery.of(context);

    return Container(
      padding: EdgeInsets.all(media.size.width * 0.02),
      child: Text(
        'Stilize Edilmiş Metin',
        style: theme.textTheme.headlineMedium,
      ),
    );
  }
}

BuildContext aracılığıyla navigasyon örneği. Navigator.of(context), ağaçta yukarı doğru en yakın Navigator’ı bulmak için bağlamı kullanır:

dart
class _NavigateButtonState extends State<NavigateButton> {
  void _navigate() {
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (_) => const DetailsScreen(),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _navigate,
      child: const Text('Detaylara Git'),
    );
  }
}

BuildContext aracılığıyla bir widget’ın boyutunu bulma örneği. findRenderObject() yöntemi, boyutun alınabileceği bir RenderObject döndürür:

dart
void _printSize(BuildContext context) {
  final renderBox = context.findRenderObject() as RenderBox?;
  if (renderBox != null) {
    print('Widget boyutu: ${renderBox.size}');
  }
}

Önemli: findRenderObject(), widget henüz monte edilmemişse veya zaten demonte edilmişse null döndürür. Kullanmadan önce sonucu her zaman null için kontrol edin. Yapım tamamlanmadan önce build içinde bu yöntemi çağırmak da null döndürebilir.

InheritedWidget ve BuildContext

InheritedWidget, BuildContext aracılığıyla ağaçta aşağıya doğru verileri verimli bir şekilde yayan özel bir widget’tır. Bir alt widget MyInheritedWidget.of(context) çağırdığında, BuildContext ağaçta yukarı doğru ilerler, eşleşen türdeki en yakın InheritedWidget’ı bulur ve verilerini döndürür. Aynı anda bağlam değişikliklere abone olur: InheritedWidget değişirse, abone olan tüm widget’lar otomatik olarak yeniden oluşturulur.

BuildContext + InheritedWidget kombinasyonu, global değişkenlerin ve prop drilling’in (yapıcı zinciri aracılığıyla veri iletme) yerini alır. 10 seviye widget üzerinden bir tema iletmek yerine, her widget doğrudan Theme.of(context) aracılığıyla erişebilir. Bu, kodu daha temiz hale getirir ve iletilen parametre sayısını azaltır.

Flutter Ekibi’ne (Google, Nisan 2026) göre InheritedWidget o kadar verimli bir mekanizmadır ki tüm resmi durum yönetimi çözümleri bunun üzerine inşa edilmiştir: Provider, InheritedWidget’ı sarar; Riverpod, onu katmanlarından biri olarak kullanır; ve Flutter SDK’nın kendisi (Theme, MediaQuery, Navigator, Localizations) tamamen bu mimariye dayanır.

Kendi InheritedWidget’ınızı Oluşturma

Kendi InheritedWidget’ınızı oluşturmak, harici bağımlılıklar olmadan veri yaymanıza olanak tanır. Sınıf, InheritedWidget’ı genişletir ve statik bir of(BuildContext context) yöntemi sağlar. Bu, basit senaryolar için Provider’a minimal bir alternatiftir:

dart
class AppConfig extends InheritedWidget {
  final String apiUrl;
  final bool useDarkMode;

  const AppConfig({
    super.key,
    required this.apiUrl,
    required this.useDarkMode,
    required super.child,
  });

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

  @override
  bool updateShouldNotify(AppConfig oldWidget) {
    return apiUrl != oldWidget.apiUrl || useDarkMode != oldWidget.useDarkMode;
  }
}

Artık ağaçta daha aşağıdaki herhangi bir widget yapılandırmaya erişebilir: final config = AppConfig.of(context);. Yapılandırma değişirse, abone olan tüm widget’lar otomatik olarak yeniden oluşturulacaktır.

Yaygın Hatalar

İlk yaygın hata, dispose’tan sonra BuildContext’i saklamak veya mounted kontrolü yapmadan async callback’te kullanmaktır. BuildContext bir öğeye bağlıdır ve öğe yok edilebilir (widget ağaçtan kaldırıldığında). Öğe yok edildikten sonra bağlamı kullanmak istisnaya yol açar. Çözüm, context.mounted (daha yeni Flutter sürümlerinde mevcut) kullanmak veya State‘te mounted‘ı kontrol etmektir.

İkinci hata, initState‘te Theme.of(context) çağırmaktır. initState aşamasında bağlam henüz ağaçta tamamen monte edilmemiştir. initState‘te InheritedWidget aramak null döndürebilir veya istisna fırlatabilir. Tüm of(context) çağrıları, bağlamın ağaçta olması garanti edilen build veya didChangeDependencies içinde yapılmalıdır.

Üçüncü hata, bir widget’ın BuildContext‘ini başka bir widget’ı manipüle etmek için kullanmaktır. BuildContext, ebeveyn-çocuk hiyerarşisi dışında widget’lar arası etkileşim için tasarlanmamıştır. Başka bir widget’ın durumunu yönetmeniz gerekiyorsa, callback, denetleyici veya durum yönetimi araçları kullanın.

Dördüncü hata, BuildContext‘i widget’ın dispose’undan daha uzun yaşayan bir async fonksiyona iletmektir. Tipik bir senaryo: Navigator.of(context) bir değişkende saklanır ve kullanıcı ekrandan ayrıldıktan sonra kullanılır. Çözüm, bağlamı statik veya uzun ömürlü nesnelerde saklamamaktır.

Async İşlemlerde Bağlam

Async işlemlerde BuildContext ile çalışmak için bir güvenlik deseni: bağlamı kullanmadan önce her zaman mounted‘ı kontrol edin ve bağlamı, widget’tan daha uzun yaşayabilecek closure’larda saklamayın:

dart
Future<void> _safeNavigation(BuildContext context) async {
  await Future.delayed(const Duration(seconds: 2));
  if (!context.mounted) return;
  Navigator.of(context).push(MaterialPageRoute(...));
}

En İyi Uygulamalar

BuildContext ile çalışmak, yaşam döngüsünü ve sınırlamalarını anlamayı gerektirir. İlk kural: bağlamı yalnızca onu parametre olarak alan yöntemler içinde kullanın (build, didChangeDependencies). Bağlamı sınıf alanlarında veya statik değişkenlerde saklamayın — bu neredeyse her zaman hatalara yol açar.

İkinci kural: InheritedWidget’dan verilere erişmek için build yerine didChangeDependencies’i tercih edin. Veriler yalnızca başlatma için gerekliyse ve işleme için değilse, didChangeDependencies doğru yerdir. Bu, başlatma mantığını UI oluşumundan ayırmaya olanak tanır ve her güncellemede tekrarlanan çağrıları önler.

Üçüncü kural: async işlemlerle çalışırken, bağlama bağlı olmayan callback’ler kullanın veya mounted‘ı kontrol edin. Bir async işlem navigasyon veya temaya erişim gerektiriyorsa, bu verileri önceden (senkron bir build veya initState bağlamında) alın ve bağlamda değil, yerel değişkenlerde saklayın.

Bağlam Ne Zaman Gerekli ve Ne Zaman Değil

  • Gerekli: Theme, MediaQuery, Navigator, Localizations, ScaffoldMessenger erişimi
  • Gerekli: boyut ölçmek için RenderObject bulma
  • Gerekli: SnackBar, BottomSheet, Dialog oluşturma
  • Gerekli değil: iş mantığı yöntemlerini çağırma, HTTP istekleri, DB işlemleri
  • Gerekli değil: build dışında widget oluşturma (fabrikalarda, yapıcılarda)

Sıkça Sorulan Sorular

Flutter’da BuildContext nedir?

BuildContext, öğe ağacında bir widget’ın konumunu temsil eden bir arayüzdür. Bu sayede widget, çevresine erişir: tema, medya sorguları, gezgin ve InheritedWidget’dan veriler. Her widget’ın kendine özgü bir bağlamı vardır.

BuildContext nasıl çalışır?

BuildContext, geçerli öğeden köke doğru ağacı yukarı geçer ve istenen türdeki en yakın InheritedWidget’ı bulur. dependOnInheritedWidgetOfExactType yöntemi yalnızca verileri bulmakla kalmaz, aynı zamanda widget’ı değişikliklere abone eder — InheritedWidget güncellendiğinde widget otomatik olarak yeniden oluşturulur.

BuildContext neden sınıf alanlarında saklanmamalıdır?

BuildContext, ağaçtaki bir öğeye bağlıdır ve öğe yok edilebilir (widget kaldırılır). Widget kaldırıldıktan sonra kaydedilmiş bir bağlam kullanmak istisnaya yol açar. Async callback’te bağlam gerekiyorsa, kullanmadan önce mounted‘ı kontrol edin.

BuildContext ve Element arasındaki fark nedir?

BuildContext bir arayüz, Element ise onun uygulamasıdır. Geliştirici, belirli öğe türünü bilmeden BuildContext üzerinden çalışır. Element, Widget’ı RenderObject’a bağlayan ve yaşam döngüsünü yöneten Flutter iç mekanizmasıdır.

Başka bir widget’ın BuildContext‘ini alabilir miyim?

Başka bir widget’ın bağlamına doğrudan erişim yoktur. Ebeveyn bağlamı için State için context.findAncestorStateOfType veya anahtarlar (GlobalKey) kullanın. Çocuk için — bir callback iletin. BuildContext, hiyerarşi dışında widget’lar arası erişim için tasarlanmamıştır.

Özet

  • BuildContext — ağaçta widget’ın konumunu temsil eden ve InheritedWidget aracılığıyla hiyerarşik çevreye erişim sağlayan temel bir Flutter nesnesi
  • Arama mekanizması — BuildContext ağacı aşağıdan yukarı geçer, istenen türdeki en yakın InheritedWidget’ı bulur ve değişikliklerine abone olur
  • Ana kullanım — Theme.of(context), MediaQuery.of(context), Navigator.of(context) temalara, duyarlılığa ve navigasyona erişim için
  • BuildContext vs Element — BuildContext kamuya açık bir arayüz, Element özel bir uygulama. Geliştirici her zaman BuildContext üzerinden çalışır
  • Yaşam döngüsü — BuildContext, karşılık gelen öğe var olduğu sürece yaşar; dispose’tan sonra bağlam kullanılmamalıdır
  • Hatalar — bağlamı uzun ömürlü nesnelerde saklamak, initState‘te kullanmak, dispose’tan sonra kullanmak yaygın hata kaynaklarıdır
  • Kural — BuildContext‘i yalnızca build/didChangeDependencies içinde kullanın, saklamayın, async senaryolarda mounted‘ı kontrol edin

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