Lists & Keys

map() ile liste render etmek, key prop'u nedir, neden önemlidir, ve en yaygın hata olan index'i key olarak kullanmak -- basit örneklerle.

Başlangıç 10 dk
EN

Lists & Keys

Şimdiye kadarki örneklerde hep tek bir şeyi gösterdik -- tek bir sayaç, tek bir kullanıcı. Ama gerçek uygulamalarda çoğu zaman bir LİSTE gösterirsin: bir ürün listesi, bir yorum listesi, bir görev listesi. Bu ders, React'te listeleri render etmeyi ve key prop'unun neden önemli olduğunu anlatıyor.

map() ile Liste Render Etmek

Bir diziyi ekrana JSX elementleri olarak dökmek için JavaScript'in map() fonksiyonunu kullanırsın:

function MapRenderListExample() {
  const fruits = ["Elma", "Armut", "Muz"];

  // map(), bir dizideki her elemanı bir JSX elementine çevirir; sonuç
  // yine bir dizi (bu sefer JSX elementlerinden oluşan) olur.
  return (
    <ul>
      {fruits.map((fruit) => (
        <li key={fruit}>{fruit}</li>
      ))}
    </ul>
  );
}

map(), bir dizideki her elemanı BAŞKA bir şeye çevirip yeni bir dizi döndürür -- burada her meyve string'ini bir <li> elementine çeviriyoruz. Sonuç, JSX elementlerinden oluşan bir dizi; React bu diziyi doğrudan render edebilir.

key Prop'u Nedir?

map() ile bir liste render ederken, her elemana bir key prop'u vermen gerekir:

function KeyPropExample() {
  const users = [
    { id: 1, name: "Ayşe" },
    { id: 2, name: "Mehmet" },
    { id: 3, name: "Elif" },
  ];

  // key, mümkün olduğunca eleman ismi ya da index değil, o elemana özgü,
  // KALICI ve BENZERSİZ bir kimlik olmalı -- burada veritabanından gelen
  // id gibi.
  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

key, o listedeki elemanı BENZERSİZ şekilde tanımlayan bir string ya da sayı. Mümkünse elemanın ismi ya da index'i değil, veritabanından gelen id gibi kalıcı bir kimlik kullanılmalı.

key Neden Önemli?

key, React'e bir sonraki render'da hangi liste elemanının HANGİSİYLE aynı olduğunu söyler:

function WhyKeysMatterExample() {
  const tasks = [
    { id: 1, text: "Sütü al" },
    { id: 2, text: "Ekmek al" },
  ];

  // key, React'e "bu liste elemanı önceki render'daki HANGİ elemanla
  // aynı" olduğunu söyler. Bir eleman eklenip/silindiğinde ya da sıra
  // değiştiğinde React bunu kullanarak doğru elemanı günceller -- key
  // olmadan (ya da yanlış bir key ile) React yanlış elemanı güncelleyip
  // beklenmedik görsel hatalara (ör. input'un yanlış satıra kayması)
  // yol açabilir.
  return (
    <ul>
      {tasks.map((task) => (
        <li key={task.id}>{task.text}</li>
      ))}
    </ul>
  );
}

Liste değişmeden kaldığı sürece key fark etmez gibi görünür. Ama bir eleman eklenip/silindiğinde ya da sıralama değiştiğinde, React key'i kullanarak hangi elemanın "aynı kaldığını", hangisinin yeni olduğunu anlar -- bu sayede yalnızca gerçekten değişen kısmı günceller, listenin tamamını yeniden oluşturmaz.

Yaygın Hatalar

En yaygın hata, key olarak dizinin index'ini kullanmaktır:

function CommonKeyMistakeExample() {
  const items = ["Elma", "Armut", "Muz"];

  return (
    <ul>
      {/* YAYGIN HATA: index'i key olarak kullanmak. Liste hiç değişmediği
          sürece çalışıyor gibi görünür, ama bir eleman eklenip/silindiğinde
          ya da sıralama değiştiğinde her elemanın index'i kayar -- React
          artık yanlış elemanı "aynı eleman" sanabilir. */}
      {items.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
}

Liste hiç değişmiyorsa bu çalışıyor gibi görünür. Ama bir eleman eklendiğinde/silindiğinde ya da sıralama değiştiğinde her elemanın index'i kayar -- React, index'e bakarak "aynı eleman" sandığı şeyin aslında farklı bir eleman olduğunu anlayamaz. Bu, özellikle input içeren listelerde (bir görev listesindeki checkbox'lar gibi) yanlış elemanın güncellenmesi gibi görsel hatalara yol açabilir. Mümkün olduğunca id gibi kalıcı bir kimlik kullan; elinde gerçekten hiç kalıcı bir kimlik yoksa ve liste asla yeniden sıralanmıyor/değişmiyorsa, index bir son çare olabilir.

Özet ve Terimler Sözlüğü

Bir diziyi ekrana dökmek için map() kullanılır; her elemana, React'in listedeki değişiklikleri doğru takip edebilmesi için benzersiz bir key verilir. key olarak mümkünse kalıcı bir id kullanılmalı, dizinin index'i değil -- index kullanmak, liste değiştiğinde yanlış elemanların güncellenmesine yol açabilir.

Terimler Sözlüğü

map() — Bir dizideki her elemanı başka bir şeye çevirip yeni bir dizi döndüren JavaScript dizi metodu; React'te listeleri JSX elementlerine çevirmek için kullanılır.

key — Bir listedeki her elemana verilen, React'in render'lar arasında elemanları takip etmesini sağlayan benzersiz kimlik.

Reconciliation (Uzlaştırma) — React'in, bir önceki render ile yeni render arasındaki farkı bulup yalnızca gerçekten değişen kısımları güncellediği süreç; key, bu süreçte listelerin doğru eşleştirilmesini sağlar.

Pratik Proje

Bu kategoride (Events, State, Conditional Rendering, Lists & Keys) öğrendiğimiz kavramları bir arada kullanan, gerçek ve çalıştırılabilir bir örnek proje var: State & Events Demo -- basit bir görev listesi (task list) uygulaması.

Proje; event handler'ları (onClick/onChange/onSubmit), useState'i, önceki state'e göre güncellemeyi, state immutability'yi, ternary/&& ile conditional rendering'i ve map()+key ile liste render etmeyi bir arada gösteriyor. Bilgisayarına indirip çalıştırabilir, kodunu satır satır inceleyebilirsin:

git clone https://github.com/cdurgun/react-course-projects.git
cd react-course-projects
npm install
cd projects/state-events
npm run dev

react-course-projects deposu npm workspaces kullanır -- npm install yalnızca bir kez, depo kökünde çalıştırılır ve tüm proje klasörleri ortak bağımlılıkları paylaşır (her klasörde ayrı bir node_modules oluşmaz). Kök dizinde npm install'ı daha önce çalıştırdıysan, doğrudan cd react-course-projects/projects/state-events yapıp npm run dev demen yeterli.