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 ya da 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 listItems
e 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')
);
Bu kod, ekrana ul
kapsayıcısı ve li
ler 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')
);
Keyler
Key
ler 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 li
ler) 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 key
lere 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')
);
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.id
yi okuyabilir, ancak props.key
i 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>
);
}
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.