---
title: 'Platforma Özgü Kod'
source: 'https://academia.sh/tr/kurslar/react-native/platforma-ozgu-kod'
course: 'React Native'
language: tr
updated: '2026-10-21T05:02:54+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Platforma göre ayrışan tarifin iki ayrı ağaç ürettiğini açıklar'
    - 'Yalnız bir platformda bulunan düğümün karşılaştırmada kurulan çıktığını ölçer'
    - 'Bu karşılaştırmanın çalışma anında olan bir güncelleme olmadığını ayırt eder'
    - 'Ortak kodun payını ve platforma özgü payı iki ağacın ortak düğümleriyle sayar'
---

# Platforma Özgü Kod

Aynı ekran iki platformda farklı tarif edilebilir. Ders iki platform ağacını karşılaştırır, yalnız bir platformda bulunan anahtar düğmesinin kurulan çıktığını ve bunun çalışma anı güncellemesi olmadığını açıkça gösterir.

Önceki derslerde tek bir ağacın zamanla nasıl değiştiğini ölçtük. Bu derste iki ağaç var ve ikisi aynı anda var olmaz: biri iOS'ta, biri Android'de çalışır. Ortak kod bir ekranı tarif ederken platforma bakıp farklı düğümler üretebilir. O zaman soru şudur: iki platformun ağacı birbirine ne kadar benzer, ve fark ağaçta nasıl görünür?

Bir şeyi baştan açık söyleyelim. Bir uygulama bir anda ya iOS'ta ya Android'dedir; çalışma anında bir platformdan öbürüne geçmez. İki ağacı karşılaştırmak, yani bir platformun ağacından öbürünün ağacına akıbet çıkarmak, bir çalışma anı güncellemesi değildir. Burada karşılaştırma bir ölçü aracıdır: iki ağacın nerede ayrıldığını gösterir.

Platformu soran kod çerçevede şöyle görünür. Parça ölçülmez.

```jsx
// Platform kodu: Row
function Row({ label }) {
  return (
    <View>
      <Text>{label}</Text>
      {Platform.OS === "ios" ? <Switch /> : <Checkbox />}
    </View>
  );
}
```

`Platform.OS` çalıştığı platformun adını verir. İfade bir koşuldur: `ios` ise bir anahtar düğmesi, değilse bir onay kutusu döner. Aynı kapsayıcı ve aynı etiket, ama son çocuğun tipi platforma göre farklıdır.

## Ortak Kod, Ayrışan Tarif

Çerçevenin çekirdek tipleri iki platformda ortaktır; platforma özgü olan, o tiplerin hangisinin seçildiğidir. Ortak kod bu seçimi tarif işlevinin içinde yapar ve iki ayrı ağaç doğar. Ölçüm için önce çekirdek gerekir.

```javascript
// fate.mjs — bir guncellemenin gorunum agacindaki her dugume ne yaptigini siniflandirir
export const FATES = ["korunan", "guncellenen", "kurulan", "sokulen"];

export function el(type, props = {}, children = [], key = null) {
  return { type, props, children, key };
}

function segment(node) {
  return node.key === null ? node.type : `${node.type}[${node.key}]`;
}

function identity(node, index) {
  return node.key === null ? `#${index}` : `key:${node.key}`;
}

function sameProps(a, b) {
  const names = [...new Set([...Object.keys(a), ...Object.keys(b)])].sort();
  return names.every((n) => JSON.stringify(a[n]) === JSON.stringify(b[n]));
}

function whole(node, path, fate, ops) {
  const here = `${path}/${segment(node)}`;
  ops.push({ fate, path: here });
  node.children.forEach((child) => whole(child, here, fate, ops));
}

export function reconcile(prev, next, path = "", ops = []) {
  if (prev === null) {
    whole(next, path, "kurulan", ops);
    return ops;
  }
  if (next === null) {
    whole(prev, path, "sokulen", ops);
    return ops;
  }
  if (prev.type !== next.type || prev.key !== next.key) {
    whole(prev, path, "sokulen", ops);
    whole(next, path, "kurulan", ops);
    return ops;
  }
  const here = `${path}/${segment(next)}`;
  ops.push({ fate: sameProps(prev.props, next.props) ? "korunan" : "guncellenen", path: here });
  const before = new Map(prev.children.map((child, i) => [identity(child, i), child]));
  const matched = new Set();
  next.children.forEach((child, i) => {
    const id = identity(child, i);
    matched.add(id);
    reconcile(before.has(id) ? before.get(id) : null, child, here, ops);
  });
  prev.children.forEach((child, i) => {
    if (!matched.has(identity(child, i))) reconcile(child, null, here, ops);
  });
  return ops;
}

export function printOps(ops) {
  ops.forEach((op) => console.log(`${op.fate}: ${op.path}`));
}

export function countFates(ops) {
  for (const name of FATES) {
    console.log(`${name}: ${ops.filter((op) => op.fate === name).length}`);
  }
  console.log(`komut: ${ops.filter((op) => op.fate !== "korunan").length}`);
}
```

Bu dersin yardımcı dosyası, platform adından bir ayarlar ekranı ağacı üretir. Her iki platformda da ekran bir başlık ve bir etiket taşır. Android'de ek olarak bir anahtar düğmesi bulunur; iOS'ta bu düğüm yoktur. İkinci işlev aynı satırı iki platformda farklı tiple üretir; aşağıda karşılaştırılır.

```javascript
// settings.mjs — platform adindan ayarlar ekrani agaci uretir
import { el } from "./fate.mjs";

export function renderSettings(platform) {
  const children = [
    el("Text", { value: "Ayarlar" }),
    el("Text", { value: "Bildirimler" }),
  ];
  if (platform === "android") {
    children.push(el("Toggle", { on: true }));
  }
  return el("Settings", {}, children);
}

export function renderChoice(platform) {
  return el("Row", {}, [
    el("Text", { value: "Bildirimler" }),
    platform === "ios" ? el("Switch", { on: true }) : el("Checkbox", { on: true }),
  ]);
}
```

## Ortak Olan Ne Kadar

İlk ölçüm, aynı platformun ağacını kendisiyle karşılaştırır. Bu, ortak kodun kendi içinde tutarlı olduğunu gösteren bir referanstır: platform değişmez, akıbet de değişmez.

```javascript
// main.mjs
import { reconcile, printOps, countFates } from "./fate.mjs";
import { renderSettings } from "./settings.mjs";

const ops = reconcile(renderSettings("ios"), renderSettings("ios"));
printOps(ops);
countFates(ops);
```

```text
korunan: /Settings
korunan: /Settings/Text
korunan: /Settings/Text
korunan: 3
guncellenen: 0
kurulan: 0
sokulen: 0
komut: 0
```

Üç düğüm korunan, komut sıfır. Referans budur: iOS tarifi iOS tarifiyle karşılaştırılırsa fark yoktur. Şimdi iki platformu karşılaştıralım.

## İki Platformun Farkı

İkinci ölçüm iOS ağacını Android ağacıyla karşılaştırır. Kapsayıcı ve iki metin her ikisinde de vardır; anahtar düğmesi yalnız Android'dedir.

```javascript
// main.mjs
import { reconcile, printOps, countFates } from "./fate.mjs";
import { renderSettings } from "./settings.mjs";

const ops = reconcile(renderSettings("ios"), renderSettings("android"));
printOps(ops);
countFates(ops);
```

```text
korunan: /Settings
korunan: /Settings/Text
korunan: /Settings/Text
kurulan: /Settings/Toggle
korunan: 3
guncellenen: 0
kurulan: 1
sokulen: 0
komut: 1
```

Ortak üç düğüm korunan, `/Settings/Toggle` kurulan. Ortak kodun payı üç düğüm, platforma özgü payı bir düğümdür. Bunu şöyle okuruz: iki platformun ekranı dört düğümden üçünde birbirine eşittir. Bu bir oran değil, bir sayımdır; sayı yalnız bu iki ağaç için geçerlidir.

Kurulan sözcüğü burada dikkatle okunmalı. iOS'ta çalışan bir uygulama o anahtar düğmesini hiçbir zaman kurmaz, çünkü Android'in ağacını hiç görmez. Karşılaştırma bir geçiş değil, bir ayrımdır: "Android'de fazladan hangi düğüm var" sorusunun cevabı.

**TY10.** Model iki platformun ağacını aynı süreçte ve aynı anda üretir. Gerçekte yalnız biri üretilir ve çalıştığı platform uygulama boyunca sabit kalır. Bu model, bir karşılaştırma yapmak için gerekli bir kolaylıktır, çalışma anı davranışı değildir.

## Platform Modülü

Dosya seçiminin yanında çerçeve, çalıştığı platformu soran küçük bir modül sunar. Modül platformun adını verir ve değerleri bir tablodan seçmeye yarayan bir yardımcı içerir: iOS için bir değer, Android için başka bir değer yazılır, çalışan platformunki döner. Bu iki yol aynı işi görür; birinde seçim bir ifadenin içinde, öbüründe dosya adında yapılır. Küçük farklar için, örneğin bir kenar boşluğunun iki platformda başka olması için, modül yeterlidir; bütün bir ekran parçasının iki platformda ayrı yazılması gerekiyorsa dosya yolu daha temiz kalır.

Karar verirken tek bir soru işe yarar: ayrışma görünümün bir ayrıntısı mı, yoksa davranışın kendisi mi? Ayrıntıysa ağaçta bir özellik farkı olarak görünür ve karşılaştırmada güncellenen çıkar. Davranışsa ağaçta farklı tipler ya da farklı düğümler doğar ve karşılaştırma kurulan ile sökülen verir. Özellik farkı ortak payı yüksek tutar; tip farkı onu düşürür. Bu yüzden ayrışmayı mümkün olan en küçük düğümde yapmak, ortak payı korumanın yoludur.

## Dosya Uzantısıyla Seçim

Platforma göre ayrışmanın tek yolu bir koşul yazmak değildir. Çerçeve, aynı adı taşıyan ama platformu uzantısında belirten dosyalar arasında seçim yapabilir: bir dosyanın iOS için, bir başkasının Android için yazılmış hâli yan yana durur ve içe aktarma yalnız ortak adı yazar. Çalışan platform hangi dosyayı seçeceğini belirler; kodda hiçbir `if` yoktur.

```jsx
// Platform kodu: Toggle
// Toggle.ios.js    -> iOS icin yazilmis dosya
// Toggle.android.js -> Android icin yazilmis dosya
import Toggle from "./Toggle";

function Row() {
  return <Toggle on={true} />;
}
```

Parçadaki ilk iki satır dosya adlarını gösteren yorumdur; kod, yalnız ortak adı içe aktarır. Hangi dosyanın kullanılacağı uygulama paketlenirken seçilir: her platform için ayrı bir paket kurulur, iOS paketine `.ios` uzantılı dosya, Android paketine `.android` uzantılı dosya girer. Bu yöntemin yararı, platforma özgü kodun ayrı dosyalarda durması ve ortak dosyaların koşullarla dolmamasıdır. Bedeli ise iki dosyanın birbirinden sapabilmesidir: biri güncellenir, öbürü unutulursa iki platform sessizce farklılaşır. Ağaç bu sapmayı, iki platformun ağacını karşılaştırdığımızda gösterir.

## Aynı Yerde, Farklı Tip

Platforma özgü ayrışma yalnız fazladan bir düğümden ibaret değildir. Aynı konumdaki düğüm iki platformda farklı tipte olabilir: iOS'ta bir anahtar düğmesi, Android'de bir onay kutusu. Bu durumda karşılaştırma, bir önceki dersin tip değişimini bu kez platformlar arasında yeniden görür.

```javascript
// main.mjs
import { reconcile, printOps, countFates } from "./fate.mjs";
import { renderChoice } from "./settings.mjs";

const ops = reconcile(renderChoice("ios"), renderChoice("android"));
printOps(ops);
countFates(ops);
```

```text
korunan: /Row
korunan: /Row/Text
sokulen: /Row/Switch
kurulan: /Row/Checkbox
korunan: 2
guncellenen: 0
kurulan: 1
sokulen: 1
komut: 2
```

Kapsayıcı ve etiket korunan, anahtar düğmesi sökülen, onay kutusu kurulan çıktı; komut iki. Dört düğümde ikisi ortak. Önceki ölçümde platforma özgü pay tek bir düğümdü, burada iki düğümdür: aynı konum, ama bir tip yerine başka bir tip. Aynı ekranın iki platformda "aynı" olması, ağaçta düğümlerin aynı olması anlamına gelmez. Tek kod tabanı aynı ekranı garanti etmez; garanti ettiği, ekranın iki platformda aynı kaynaktan üretilmesidir.

Burada bir yanılgıyı ayıklayalım: "Ortak kod yazdım, o halde iki platform aynı ekranı gösteriyor." Ortak kod iki ağaç üretebilir ve ağaçlar farklıysa yerel taraf farklı görünümler kurar. Ortak payı artırmak isteyen kişi bu karşılaştırmayı bir kontrol aracı olarak kullanabilir: ayrışan her düğüm ya bilerek bırakılmış bir platform farkıdır ya da farkında olunmadan gelmiş bir sapmadır. Ağaç hangisinin hangisi olduğunu söylemez; yalnız nerede ayrıldığını gösterir.

## Sınırlayıcı Ölçüm

Odak düğüm `/Settings/Toggle`'dır. Son ölçüm, ayrışmanın tersini de sınar: Android ağacından iOS ağacına bakıldığında anahtar düğmesi yok olur.

```javascript
// main.mjs
import { reconcile, printOps, countFates } from "./fate.mjs";
import { renderSettings } from "./settings.mjs";

const ops = reconcile(renderSettings("android"), renderSettings("ios"));
printOps(ops);
countFates(ops);
```

```text
korunan: /Settings
korunan: /Settings/Text
korunan: /Settings/Text
sokulen: /Settings/Toggle
korunan: 3
guncellenen: 0
kurulan: 0
sokulen: 1
komut: 1
```

Yön değişince akıbet de değişti: Android'den iOS'a bakınca anahtar düğmesi sökülen, iOS'tan Android'e bakınca kurulan çıktı. Ortak üç düğüm iki yönde de korunan. Karşılaştırmanın bir yönü vardır ve akıbet o yöne bağlıdır; ama hangi yönden bakılırsa bakılsın, ortak ve ayrışan payın büyüklüğü aynıdır.

Bu dersin akıbeti kurulandır, ama sınırı baştan yazılmalıdır: bu kurulan, çalışma anında olan bir güncellemeden gelmedi. Bir ağacın öbürüyle karşılaştırılmasından geldi. Platforma özgü koda bakarken kullandığımız ölçü bu: iki ağaç kaç düğümde ortak, kaç düğümde ayrışıyor.

Bu, M32/K01'in sorusundan farklıdır. O derste paylaşımı ölçtük: kodun ne kadarı iki platformda ortak. Burada paylaşım ölçülmedi; ölçülen, iki platformun ağacındaki bir düğümün karşılaştırmada ne akıbet aldığıdır. Ortak olan bir düğümün de platformda aynı yerel görünüme karşılık geldiğini söylemiyoruz.

**TY11.** Model, ortak tipleri iki platformda aynı sayar. Gerçekte aynı tip, platforma göre farklı yerel görünüm üretir; ağaçta tip adı aynıdır ve fark görünmez.

Model, bu akıbetin kuralını kurar; model çerçevenin kendisi değildir.

Son bir ölçüt olarak iki ölçümü yan yana koyalım. Ayarlar ekranında dört düğümün üçü ortak, biri ayrışıyordu. Seçim satırında dört düğümün ikisi ortak, ikisi ayrışıyordu. İlk durumda ayrışma ekrana bir şey ekliyor, ikincisinde bir şeyi değiştiriyor. Bir ekranın ortak payını artırmak isteyen kişi önce hangi tür ayrışmanın olduğuna bakmalıdır; çünkü eklemeyi koşullu bir düğümle, değiştirmeyi ise yalnız o düğümün tipini seçerek çözmek mümkündür ve ikisi de kapsayıcıya ve kardeşlere dokunmaz.

Bu ölçümlerin sınırını da belirtelim. Karşılaştırdığımız ağaçlar yalnız tipleri ve özellikleri taşır; iki platformun yerel görünümlerinin ekranda nasıl göründüğü, hangi yazı tipini kullandığı ya da kenar boşluklarını nasıl hesapladığı ağaçta yoktur. Bu yüzden "ortak pay yüksek" sonucu, ekranların birbirine benzediği anlamına gelmez; yalnız tariflerin benzediği anlamına gelir. Görünümlerin benzemesi için ayrıca gözle bakmak gerekir, ve bu kursun ölçüsü onu kapsamaz.

Son olarak, bu dersin neden çalışma anı güncellemesi olmadığını yeniden vurgulayalım, çünkü ölçüm çıktısındaki `kurulan` sözcüğü yanıltabilir. Uygulama yüklendiği platformda baştan sona aynı ağacı üretir. Platform değişmediği için `renderSettings("android")` ile `renderSettings("ios")` bir uygulamanın yaşamında hiçbir zaman art arda çağrılmaz. Çalışma anında gerçekleşen güncellemeler, platform içinde, durum değiştikçe olur ve onları önceki derslerin ölçümleri gösterdi. Bu derste iki ağacı yan yana koymak, ayrışmayı görünür kılmak için kullanılan bir araçtır.

Ortak kodun payını sayarken küçük bir tuzak vardır: sayı, ağacın boyutuna bağlıdır. Dört düğümlü bir ekranda bir ayrışan düğüm büyük bir pay gibi görünür; yüz düğümlü bir ekranda aynı tek düğüm göze çarpmaz. Bu yüzden sayıları ekranlar arasında karşılaştırmadan önce düğüm sayılarına bakmak gerekir. Bu derste her sayı yalnız o ölçümün iki ağacı için geçerlidir ve genellenmez. Genelleme yapmak isteyen kişi aynı ölçümü kendi ekranlarında yeniden kurar.

Bir kontrol listesi de işe yarar. Ayrışma eklemeden önce şunlar sorulur: fark gerçekten platformdan mı geliyor, yoksa tasarım kararsızlığından mı? Ayrışan düğüm en küçük düğüm mü? Ayrışmanın iki ağaçtaki karşılığı ölçülüp ortak pay kaydedildi mi? Üç sorunun cevabı açıksa ayrışma bilerek yapılmış sayılır.

## Özet

- Bu dersin akıbeti: kurulan. İkinci ölçümde yalnız Android'de bulunan `/Settings/Toggle` iOS ağacından Android ağacına bakılınca kurulan çıktı; bu bir çalışma anı güncellemesi değil, iki ağacın karşılaştırmasıdır.
- Platforma göre ayrışan tarif iki ayrı ağaç üretir; uygulama yalnız birini görür.
- Ortak kodun payı ortak düğümlerle, platforma özgü payı ayrışan düğümlerle sayılır: dört düğümde üç ortak, bir ayrışan.
- Karşılaştırmanın yönü akıbeti belirler: aynı düğüm bir yönde kurulan, öbür yönde sökülen çıkar.
- Aynı tip adı iki platformda aynı yerel görünümü garanti etmez; ağaç bu farkı göstermez.

## Sonraki Adım

Çekirdek yapı burada tamamlanır: ağaç, bileşenler, biçem, dokunma ve platform farkı. Sıradaki konu, `Gezinme`, ekranlar arasında geçişin ağaca ne yaptığını ele alır: bir ekran gidip öbürü gelince hangi düğümler sökülür ve kurulur.
