Listeler ve Keyler

Önce, JavaScript’te listeleri nasıl dönüştürdüğümüzü gözden geçirelim. Aşağıdaki kod göz önüne alındığında, bir dizi sayı almak ve değerlerini ikiye katlamak için map() fonksiyonunu kullanıyoruz. map() tarafından return edilen çift katlı değerleri kaydederiz:

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);

Konsola [2, 4, 6, 8, 10] yazacaktır.

Google Chrome’da (diğer tarayıcılarda da benzer yada aynıdır) F12‘ye basıp, “Console (yada Konsol)” sekmesine gelip bu kodları yapıştırarak test edebilirsiniz.

Ok fonksiyonları ile ilgili dokümantasyon hazırlandığında bu kısım güncellenecektir. Kısaca özet geçmek gerekirse yukarıda map fonksiyonunun içerisinde yapılan işlem ((number) => number * 2) şudur:

number parametre alınır ve number*2 return edilir.

Fonksiyonun kolay okunabilir hali ise şudur: </i>

function(number) {
  return number*2;
}

React’te, dizi elemanlarını listelere dönüştürmek neredeyse aynıdır.

Birden Çok Component Vermek

Koleksiyonları oluşturabilir ve bunları JSX içine süslü parantez {} kullanarak ekleyebilirsiniz.

Aşağıda, JavaScript map() fonksiyonu kullanarak numbers dizisinde döngü oluşturuyoruz. Her liste için bir <li> return ediyoruz. Son olarak, elde edilen sonuç dizisini listItemse atayacağız:

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li>{number}</li>
);

Bütün listItems dizesini <ul> elemanının içerisine dahil ediyoruz ve bunu DOM’a gönderiyoruz:

ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('root')
);

CodePen’de Deneyin

Bu kod, ekrana ul kapsayıcısı ve liler içerisinde rakamları yazacaktır.

Temel Liste Componenti

Genellikle listeleri bir component içinde render ederiz.

Önceki örneği, numbers adında bir dizi kabul eden ve liste çıktısı yapan bir componente dönüştürebiliriz.

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li>{number}</li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

Bu kodu çalıştırdığınızda, liste için bir key (anahtar) verilmesi yönünde bir uyarı verilir.

Burada key kelimesine (Türkçe’si anahtar demek olmasına rağmen) anahtar çevirisi tam olarak uymuyor. Key denirken aslında benzersizi ifade etmektedir (ID, Kimlik numarası, parmak izi gibi).

Bir key, listeleri oluşturulurken eklenmesi gereken özel bir attribute’tür. Bir sonraki bölümde bunun neden önemli olduğunu anlatacağız. numbers.map() içindeki listelere birer key atayalım.

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

CodePen’de Deneyin

Keyler

Keyler yardımı ile hangi listenin değiştiğini, eklendiğini veya kaldırıldığını belirleyebiliriz. Elemanlara istikrarlı bir kimlik kazandırmak için dizideki listelere key verilmelidir:

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);

Bir key seçmenin en iyi yolu, kardeşleri (diğer liler) arasında bir tanımlanan bir kimlik kullanmaktır. Çoğu zaman, verilerinizdeki id’ler key olarak kullanılır:

const todoItems = todos.map((todo) =>
  <li key={todo.id}>
    {todo.text}
  </li>
);

Eğer bu tarzda bir yapınız yoksa benzersiz olacağı için keylere index verebiliriz:

const todoItems = todos.map((todo, index) =>
  // Listelerin benzersiz id'leri yoksa bu yöntemi kullanın.
  <li key={index}>
    {todo.text}
  </li>
);

Listelerin sırası değişebilirse keyler için index kullanmanızı önermiyoruz. Bu, performansı olumsuz etkileyebilir ve component state’i ile ilgili sorunlara neden olabilir.

Ayrıntılı bilgi için Robin Pokorny‘nin makalesini inceleyebilirsiniz (İngilizce).

Listelere siz key atamazsanız React varsayılan olarak index’i atar.

Keyler Yalnızca Kardeşleri Arasında Benzersiz Olmalıdır

Dizilerde kullanılan keyler kardeşleri arasında benzersiz olmalıdır. Bununla birlikte, global olarak benzersiz olması gerekmez.

İki farklı diziyi üretirken aynı keyleri kullanabiliriz:

function Blog(props) {
  const sidebar = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post) =>
    <div key={post.id}>
      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  );
  return (
    <div>
      {sidebar}
      <hr />
      {content}
    </div>
  );
}

const posts = [
  {id: 1, title: 'Merhaba Dünya', content: 'React Öğreniyoruz!'},
  {id: 2, title: 'Ömer Gülçiçek', content: 'React JS Türkçe Dokümantasyon'}
];
ReactDOM.render(
    <Blog posts={posts} />,
    document.getElementById('root')
);

CodePen’de Deneyin

Keyler React’te bir ipucu işlevi görür ancak componentlere aktarılmazlar. Componentlerde aynı değere ihtiyacınız varsa, açıkça farklı bir ada sahip bir props olarak iletebilirsiniz:

const content = posts.map((post) =>
  <Post
    key={post.id}
    id={post.id}
    title={post.title} />
);

Yukarıdaki örnekte, Post componenti props.idyi okuyabilir, ancak props.keyi okuyamaz.

map() Fonksiyonunu JSX İçine Karıştırmak

Yukarıdaki örneklerde hep farklı bir listItems değişkeni tanımlayıp ve JSX’e dahil ettik:

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

JSX, herhangi bir ifadeyi süslü parantez içine yerleştirmeye izin verir, böylece map() fonksiyonu ile sonucu sıralayabiliriz:

function NumberList(props) {
  const numbers = props.numbers;
  return (
    <ul>
      {numbers.map((number) =>
        <ListItem key={number.toString()}
                  value={number} />
      )}
    </ul>
  );
}

CodePen’de Deneyin

Bazen bu daha temiz koda neden olur, ancak bu stil de istismar edilebilir. JavaScript’te olduğu gibi okunabilirlik açısından bir değişkenin çıkartılmaya değer olup olmadığına karar vermek size aittir. Kod çok iç içe geçmişse, bir componenti ayıklamak için doğru zamanın geldiğini aklınızda bulundurun.

Sıradaki Eğitim: Formlar