---
title: 'Bağlam Aktarımı'
source: 'https://academia.sh/tr/kurslar/bilesen-tabanli-gelistirme/baglam-aktarimi'
course: 'Bileşen Tabanlı Arayüz Geliştirme'
language: tr
updated: '2026-08-17T18:09:12+00:00'
license: 'CC BY-SA 4.0'
---

# Bağlam Aktarımı

Bir değeri ağaçta sağlayıp aşağıdaki herhangi bir düğümde okumak; özellik zincirinin sorunu, sağlayıcının yukarı doğru çözümlenmesi, en yakın sağlayıcının gölgelemesi, sağlanan değerin kimliğinin tüketici sayısına etkisi ve bağlamın uygun olmadığı yerler.

Önceki dersin üç saklama biçimi de tek bir bileşenin içinde kalır. Değerin başka bir
bileşene ulaşması için bilinen tek yol vardır: üstten alta doğru özellik olarak verilmek.
Ölçüm istasyonu sayfasında bu yol uzar. Sıcaklığın santigrat mı fahrenhayt mı gösterileceği
sayfanın en üstünde seçilir; bu bilgiye ihtiyaç duyan yer en altta, tablo satırının içindeki
ölçüm rozetidir. Aradaki dört bileşen — sayfa gövdesi, ölçüm tablosu, tablo satırı, hücre —
birimi hiç kullanmaz, yalnız taşır.

Bu ders zinciri kısaltan mekanizmayı kurar: değeri ağacın bir düğümünde **sağlamak** ve
altındaki herhangi bir düğümde, aradakilere hiç dokunmadan **okumak**.

## Özellik Zincirinin Sorunu

Bir değerin ara bileşenlerden geçirilerek taşınmasına **özellik zinciri (prop
drilling)** denir. Zincirin kendisi bir hata değildir; iki üç düzey için en açık çözüm
budur. Uzadıkça üç ayrı maliyet üretir.

Birincisi arayüz genişlemesidir. Ölçüm tablosunun API'sinde artık bir birim parametresi
vardır, oysa tablo birimle hiç ilgilenmez. Bileşenin dışarıdan görünen sözleşmesi, kendi
işini anlatmayan alanlarla dolar.

İkincisi değişim maliyetidir. Zincire yeni bir değer eklemek — yerel ayar, ondalık basamak
sayısı, eşik renkleri — aradaki her bileşende bir imza değişikliği demektir. Beş düzeyli bir
zincire üç değer eklemek on beş dosyaya dokunmaktır.

Üçüncüsü yeniden kullanımdır. Birimi taşımak zorunda olan bir tablo, birimin olmadığı bir
sayfada kullanılamaz; parametre isteğe bağlı yapıldığında ise varsayılanın nereden geleceği
sorusu doğar.

## Sağlayıcı ve Çözümleme

Bağlam bu üç maliyeti ortadan kaldırır. Ağacın bir düğümü bir anahtar altında değer
**sağlar**; o düğümün altındaki herhangi bir bileşen aynı anahtarla değeri okur. Aradaki
bileşenlerin haberi olmaz.

Okuma bir arama işlemidir: bileşen kendi düğümünden başlar, ata zinciri boyunca yukarı
çıkar ve o anahtarı sağlayan ilk düğümde durur. Hiçbir düğüm sağlamıyorsa bağlamın
tanımıyla birlikte verilen varsayılan değer kullanılır.

```js
// baglam-cozumleme.mjs — saglayicinin agacta yukari dogru aranmasi
const dugum = (ad, saglanan, cocuklar = []) => {
  const d = { ad, saglanan, cocuklar, ust: null };
  for (const c of cocuklar) c.ust = d;
  return d;
};

const VARSAYILAN = { birim: "kelvin" };   // hicbir saglayici yoksa kullanilir

function coz(baslangic, anahtar) {
  let d = baslangic;
  let adim = 0;
  while (d) {
    if (d.saglanan && anahtar in d.saglanan)
      return { deger: d.saglanan[anahtar], saglayici: d.ad, adim };
    d = d.ust;
    adim++;
  }
  return { deger: VARSAYILAN[anahtar], saglayici: "(varsayilan)", adim };
}

const rozet1 = dugum("rozet-1");
const rozet2 = dugum("rozet-2");
const rozet3 = dugum("rozet-3");
const sayfa = dugum("sayfa", { birim: "santigrat" }, [
  dugum("baslik"),
  dugum("suzgec-paneli", null, [dugum("suzgec-listesi", null, [rozet3])]),
  dugum("olcum-tablosu", null, [
    dugum("satir-1", null, [rozet1]),
    dugum("karsilastirma-panosu", { birim: "fahrenhayt" }, [rozet2]),
  ]),
]);
const ayrikRozet = dugum("ayrik-rozet");   // agacin disinda

console.log(`kok: ${sayfa.ad}`);
for (const d of [rozet1, rozet2, rozet3, ayrikRozet]) {
  const s = coz(d, "birim");
  console.log(
    `  ${d.ad.padEnd(12)} birim=${s.deger.padEnd(10)}`,
    `kaynak=${s.saglayici.padEnd(21)} ${s.adim} ust dugum tarandi`,
  );
}
```

```
kok: sayfa
  rozet-1      birim=santigrat  kaynak=sayfa                 3 ust dugum tarandi
  rozet-2      birim=fahrenhayt kaynak=karsilastirma-panosu  1 ust dugum tarandi
  rozet-3      birim=santigrat  kaynak=sayfa                 3 ust dugum tarandi
  ayrik-rozet  birim=kelvin     kaynak=(varsayilan)          1 ust dugum tarandi
```

Dört satır dört ayrı davranışı gösterir. Birinci rozet üç düzey yukarıdaki sayfa
sağlayıcısını bulmuştur; aradaki tablo ve satır bileşenleri birimi hiç görmemiştir.

İkinci rozet karşılaştırma panosunun içindedir ve bir düzey yukarıdaki sağlayıcıda durur.
Sayfa sağlayıcısı hâlâ oradadır, ama aranmaz: **en yakın sağlayıcı kazanır.** Bu, aynı
sayfada bir bölümün farklı bir birimle gösterilmesini olanaklı kılar.

Üçüncü rozet ağacın bambaşka bir dalındadır ve yine sayfa sağlayıcısını bulur. Bağlam bir
dala değil, bir alt ağaca yayılır.

Dördüncü rozet hiçbir sağlayıcının altında değildir ve varsayılana düşer. Varsayılanın
anlamlı seçilmesi bir tasarım işidir: bağlam olmadan da çalışan bir bileşen, tek başına
sınanabilir ve başka bir sayfada yeniden kullanılabilir.

## Bağlam Sözcüksel Değil, Konumsaldır

Bu mekanizmanın en çok yanlış anlaşılan yanı, benzediği şeyden ayrıldığı noktadır.
Programlama Temelleri kursundaki kapsam **sözcükseldir**: bir işlevin gördüğü değişkenler,
o işlevin kaynak kodda nerede yazıldığına bağlıdır. Bağlam ise **konumsaldır**: bir
bileşenin gördüğü değer, o bileşenin ağaçta nereye yerleştirildiğine bağlıdır.

Aynı ölçüm rozeti kaynakta bir kez yazılır; tablonun içinde santigrat, karşılaştırma
panosunun içinde fahrenhayt okur. Kaynak kod değişmemiştir, yer değişmiştir.

En yakın sağlayıcının kazanması, aynı kursta tanımlanan **gölgelemenin** ağaç üzerindeki
karşılığıdır: iç sağlayıcı, dıştakini kendi alt ağacında görünmez kılar. Bu güç bir
maliyetle gelir. Bir bileşenin hangi değeri okuyacağını anlamak için tanımına bakmak
yetmez; ağaçtaki yerini bilmek gerekir. Bu yüzden bağlamla taşınan değerler az sayıda ve
adları açık olmalıdır.

## Değişimin Maliyeti

Sağlanan değer değiştiğinde, o bağlamı okuyan bütün bileşenler yeniden çizilir —
ağaçta nerede olurlarsa olsunlar, aradaki bileşenler değişmemiş olsa bile. Sağlanan değerin
kimliği bu yüzden doğrudan bir maliyet kalemidir.

```js
// baglam-maliyeti.mjs — saglanan degerin kimliginin tuketici sayisina etkisi
const BIRIM_TUKETICI = 6;    // birimi okuyan bilesen sayisi
const SATIR_TUKETICI = 2;    // secili satiri okuyan bilesen sayisi

const OLAYLAR = [
  { ad: "panel acildi",    birim: "santigrat",  secili: null },
  { ad: "satir 1 secildi", birim: "santigrat",  secili: 1 },
  { ad: "satir 2 secildi", birim: "santigrat",  secili: 2 },
  { ad: "birim degisti",   birim: "fahrenhayt", secili: 2 },
];

function calistir(strateji) {
  let oncekiBirim = "santigrat";     // ilk olusturmada kurulan degerler
  let oncekiSecili = null;
  let toplam = 0;
  console.log(`${strateji}:`);
  for (const olay of OLAYLAR) {
    let sayi = 0;
    if (strateji === "govdede kurulan nesne") {
      sayi = BIRIM_TUKETICI + SATIR_TUKETICI;          // kimlik her olusturmada degisir
    } else if (strateji === "bellenmis tek baglam") {
      const degisti = olay.birim !== oncekiBirim || olay.secili !== oncekiSecili;
      sayi = degisti ? BIRIM_TUKETICI + SATIR_TUKETICI : 0;
    } else {
      if (olay.birim !== oncekiBirim) sayi += BIRIM_TUKETICI;
      if (olay.secili !== oncekiSecili) sayi += SATIR_TUKETICI;
    }
    oncekiBirim = olay.birim;
    oncekiSecili = olay.secili;
    toplam += sayi;
    console.log(`  ${olay.ad.padEnd(15)} -> yeniden cizilen tuketici: ${sayi}`);
  }
  console.log(`  toplam: ${toplam}`);
}

console.log(`${BIRIM_TUKETICI} birim tuketicisi, ${SATIR_TUKETICI} satir tuketicisi, 4 olay`);
for (const s of ["govdede kurulan nesne", "bellenmis tek baglam", "iki ayri baglam"])
  calistir(s);
```

```
6 birim tuketicisi, 2 satir tuketicisi, 4 olay
govdede kurulan nesne:
  panel acildi    -> yeniden cizilen tuketici: 8
  satir 1 secildi -> yeniden cizilen tuketici: 8
  satir 2 secildi -> yeniden cizilen tuketici: 8
  birim degisti   -> yeniden cizilen tuketici: 8
  toplam: 32
bellenmis tek baglam:
  panel acildi    -> yeniden cizilen tuketici: 0
  satir 1 secildi -> yeniden cizilen tuketici: 8
  satir 2 secildi -> yeniden cizilen tuketici: 8
  birim degisti   -> yeniden cizilen tuketici: 8
  toplam: 24
iki ayri baglam:
  panel acildi    -> yeniden cizilen tuketici: 0
  satir 1 secildi -> yeniden cizilen tuketici: 2
  satir 2 secildi -> yeniden cizilen tuketici: 2
  birim degisti   -> yeniden cizilen tuketici: 6
  toplam: 10
```

Birinci strateji, sağlanan değeri sağlayıcının gövdesinde her oluşturmada yeniden kuran
yaygın yazımdır. Değerin içeriği değişmese bile kimliği değişir, dolayısıyla panelin
açılması bile sekiz tüketiciyi yeniden çizer. Bu, önceki derste kurulan kimlik
kararlılığı sorununun bağlamdaki karşılığıdır ve çözümü aynıdır: sağlanan değer bellenir.

İkinci strateji bunu yapar ve ilgisiz oluşturmaları eler; otuz iki tüketici oluşturması
yirmi dörde iner. Ama seçili satır her değiştiğinde birimi okuyan altı bileşen de yeniden
oluşturulur, çünkü ikisi tek bir nesnede taşınmaktadır.

Üçüncü strateji değerleri ayırır: seyrek değişen birim bir bağlamda, sık değişen seçim
başka bir bağlamda. Toplam ona iner. Kural buradan çıkar: **bir bağlamda birlikte taşınan
değerler aynı sıklıkta değişmelidir.** Değişim sıklıkları ayrışıyorsa bağlam bölünür.

## Bağlamın Uygun Olmadığı Yerler

Bağlam bir durum yönetimi çözümü değildir; bir taşıma yoludur. Değer yine bir yerde durum
olarak tutulur, bağlam yalnız onun ağaçta dolaşmasını sağlar.

Uygun olduğu değerler ortak bir özellik taşır: seyrek değişirler ve ağacın geniş bir
bölümünü ilgilendirirler. Görsel tema, ölçü birimi, yerel ayar, oturum açmış kullanıcı
bilgisi, biçim ayarları, erişilebilirlik tercihleri bu tanıma uyar.

Uygun olmadığı yerler de bellidir. Sık değişen bir liste — kaydırma konumu, imleç
altındaki satır, bir animasyonun ilerleme değeri — bağlamla taşındığında her değişimde
bütün tüketicileri yeniden çizer. İki bileşen arasında paylaşılan tek bir değer için
bağlam kurmak, önceki dersteki durumun yukarı taşınmasından daha karmaşık ve daha
maliyetlidir.

Son bir ölçüt sınanabilirliktir. Bağlam okuyan bir bileşen tek başına oluşturulduğunda
varsayılan değere düşer. Varsayılan anlamlıysa bileşen bağımsız olarak sınanabilir;
varsayılan yoksa ve bağlamın bulunmaması hata üretiyorsa, bileşen her sınamada bir
sağlayıcıyla sarmalanmak zorunda kalır.

## Özet

- Özellik zinciri uzadıkça ara bileşenlerin arayüzünü genişletir, değişim
  maliyetini artırır ve yeniden kullanımı zorlaştırır.
- Bağlam okuma, tüketici düğümden ata zinciri boyunca yukarı çıkıp o anahtarı sağlayan ilk
  düğümde duran bir aramadır; hiçbiri yoksa varsayılan kullanılır.
- En yakın sağlayıcı kazanır; iç sağlayıcı dıştakini kendi alt ağacında gölgeler.
- Bağlam sözcüksel değil konumsaldır: bileşenin gördüğü değer, tanımının yerine değil
  ağaçtaki konumuna bağlıdır.
- Sağlanan değer her oluşturmada yeniden kurulursa bütün tüketiciler her oluşturmada
  yeniden çizilir; değer bellenir.
- Bir bağlamda birlikte taşınan değerler aynı sıklıkta değişmelidir; sıklıklar ayrışıyorsa
  bağlam bölünür.

## Sonraki Adım

Bağlam bir değeri ağaçta aşağı doğru akıtır. Ters yönde akan bir şey daha vardır ve bu
derse kadar hiç ele alınmadı: hata. Ölçüm tablosunun bir satırı, sunucudan gelen bozuk bir
kayıt yüzünden oluşturma sırasında bir istisna atarsa ne olur? Bildirimsel bir ağaçta bu
sorunun yanıtı sanıldığından serttir: yarım kalmış bir ağaç tutarsızdır ve çalışma zamanının
elinde onu kurtaracak bir bilgi yoktur. Sonraki ders bu davranışın gerekçesini, bir alt
ağacın hatasını çevresinden yalıtan mekanizmayı ve bu mekanizmanın yakalayamadığı hata
türlerini ele alır.
