- Konu sahibi
- #1
React listelerinde
Bir liste yeniden oluşturulduğunda React yeni elemanları önceki render’daki elemanlarla karşılaştırır. Aynı konumdaki içeriğe güvenmek yerine kararlı bir
Bu kodda
Aşağıdaki kullanım, liste değişmiyorsa çalışıyor gibi görünebilir:
Ancak listenin başına yeni bir öğe eklendiğinde eski öğelerin indeksleri değişir. React, önceki ilk satırın kimliğini yeni ilk satırla eşleştirebilir.
Kararı şu şekilde verebilirsiniz:
Buradaki temel ölçüt, öğenin ekrandaki konumu değil, verideki kimliğidir. Liste sıralanabiliyor, filtrelenebiliyor, silinebiliyor veya araya kayıt eklenebiliyorsa indeks güvenilir bir kimlik değildir.
Key tek başına her state’i koruma garantisi değildir; öğenin türü ve ağaçtaki konumu da eşleştirmeyi etkiler. Bir kaydı başka bir ebeveyn altına taşımak yeni kimlik bağlamı oluşturabilir. Kimlik yerelde üretilecekse kaydı oluştururken bir kez üretip veriyle saklayın; render sırasında her seferinde UUID üretmeyin. Bir öğe birden fazla kardeş düğüm döndürüyorsa kısa Fragment yazımı yerine key alabilen açık Fragment kullanılması gerekebilir.
Doğru yerleşim şu iki kullanım arasındaki farktır:
Geliştirme ortamında React’in “Each child in a list should have a unique key” uyarısını görüyorsanız, önce
Key’i yanlış seviyeye koymak: Key, listeyi üreten
Key’i her render’da değiştirmek:
Aynı ID’yi birden fazla satırda kullanmak: Benzersizlik yalnızca uyarıyı kaldırmak için değil, doğru eşleştirme için de gereklidir. Veri kaynağı bunu garanti etmiyorsa ID’ye ek olarak güvenilir bir bağlam oluşturulmalı veya veri modeli düzeltilmelidir.
Liste değişebiliyorsa kalıcı ve benzersiz veri kimliğini
Çünkü
React yeni key’i farklı bir kimlik kabul eder. Bu nedenle önceki bileşenin yerel state’i ve yaşam döngüsü korunmaz; yeni bir bileşen oluşturulur. Bu davranış bazen formu bilinçli olarak sıfırlamak için kullanılabilir, ancak normal listelerde key’in kararlı tutulması gerekir.
key, listedeki her öğenin kardeşleri arasındaki kimliğini belirtir. React bu kimliği kullanarak bir render sonrasında hangi öğenin aynı kaldığını, hangisinin eklendiğini, silindiğini veya yer değiştirdiğini anlar. Bu nedenle key yalnızca uyarıyı susturmak için değil, arayüz durumunun doğru öğeyle eşleşmesini sağlamak için gereklidir.React key değerini nasıl kullanır?
Bir liste yeniden oluşturulduğunda React yeni elemanları önceki render’daki elemanlarla karşılaştırır. Aynı konumdaki içeriğe güvenmek yerine kararlı bir
key değeri verilirse öğenin kimliği korunur. Böylece bir input’un yazısı, bir bileşenin yerel state’i veya odak durumu yanlış satıra taşınmaz.key değeri yalnızca aynı listedeki kardeşler arasında benzersiz olmalıdır. Tüm uygulamada veya veritabanında küresel olarak benzersiz olması gerekmez. En uygun kaynak genellikle verinin kalıcı id alanıdır:
Kod:
function TodoList({ todos }) {
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
}
Bu kodda
todos sıralansa, araya yeni bir kayıt girse veya bir kayıt silinse bile React her satırı todo.id üzerinden tanıyabilir.Somut örnek: neden dizi indeksine güvenilmez?
Aşağıdaki kullanım, liste değişmiyorsa çalışıyor gibi görünebilir:
Kod:
{items.map((item, index) => (
<Row key={index} item={item} />
))}
Ancak listenin başına yeni bir öğe eklendiğinde eski öğelerin indeksleri değişir. React, önceki ilk satırın kimliğini yeni ilk satırla eşleştirebilir.
Row içinde input veya yerel state varsa bu state görsel olarak başka veriye aitmiş gibi görünebilir.Kararı şu şekilde verebilirsiniz:
| Key kaynağı | Uygunluk | Neden |
|---|---|---|
| Kalıcı veri ID’si | Tercih edilir | Öğe taşınsa veya silinse de kimliği değişmez. |
| Dizi indeksi | Sınırlı kullanım | Yalnızca liste sabitse ve yeniden sıralanmıyor, eklenmiyor veya silinmiyorsa düşünülebilir. |
| Rastgele değer | Kullanmayın | Her render’da değişerek öğelerin sürekli yeni kabul edilmesine yol açar. |
Buradaki temel ölçüt, öğenin ekrandaki konumu değil, verideki kimliğidir. Liste sıralanabiliyor, filtrelenebiliyor, silinebiliyor veya araya kayıt eklenebiliyorsa indeks güvenilir bir kimlik değildir.
Key tek başına her state’i koruma garantisi değildir; öğenin türü ve ağaçtaki konumu da eşleştirmeyi etkiler. Bir kaydı başka bir ebeveyn altına taşımak yeni kimlik bağlamı oluşturabilir. Kimlik yerelde üretilecekse kaydı oluştururken bir kez üretip veriyle saklayın; render sırasında her seferinde UUID üretmeyin. Bir öğe birden fazla kardeş düğüm döndürüyorsa kısa Fragment yazımı yerine key alabilen açık Fragment kullanılması gerekebilir.
Uygularken izlenecek adımlar
- Listenin her öğesinde değişmeyen bir alan belirleyin; örneğin
id,slugveya uygulamanın ürettiği kalıcı bir kimlik. - Bu alanı, doğrudan
map()içindeki en dış JSX öğesinekeyolarak verin. - Aynı listedeki iki öğenin aynı değeri üretmediğini kontrol edin. Eksik veya tekrarlanan ID varsa önce veri kaynağını düzeltin.
- Liste sıralama, ekleme veya silme destekliyorsa
key={index}kullanımını kaldırın. - Bileşenin
keydeğerini içeride okumaya çalışmayın.key, React’in kendi eşleştirmesi içindir; bileşene veri olarak gerekiyorsa ayrıcaitemId={item.id}gönderin.
Doğru yerleşim şu iki kullanım arasındaki farktır:
Kod:
// React kimliği olarak key, bileşene ayrıca veri olarak itemId
<Row key={item.id} itemId={item.id} item={item} />
Kod:
function Row({ itemId, item }) {
// itemId burada kullanılabilir; key prop olarak gelmez.
return <li data-item-id={itemId}>{item.text}</li>;
}
Geliştirme ortamında React’in “Each child in a list should have a unique key” uyarısını görüyorsanız, önce
map() sonucundaki en dış öğeyi ve iç içe listeleri inceleyin. Key’i rastgele bir değerle değiştirmek uyarıyı geçici olarak gizleyebilir ama kimlik sorununu çözmez.Sık yapılan hatalar
Key’i yanlış seviyeye koymak: Key, listeyi üreten
map() çağrısının doğrudan döndürdüğü elemana verilmelidir. Alt bileşenin içinde vermek React’in dış listedeki eşleştirmesini düzeltmez.Key’i her render’da değiştirmek:
Math.random() veya zaman bilgisinden üretilen değerler her çizimde farklıdır. React bu durumda aynı öğeyi korumak yerine yeni bir öğe gibi ele alabilir; input değerleri ve yerel state sıfırlanabilir.Aynı ID’yi birden fazla satırda kullanmak: Benzersizlik yalnızca uyarıyı kaldırmak için değil, doğru eşleştirme için de gereklidir. Veri kaynağı bunu garanti etmiyorsa ID’ye ek olarak güvenilir bir bağlam oluşturulmalı veya veri modeli düzeltilmelidir.
Liste değişebiliyorsa kalıcı ve benzersiz veri kimliğini
key yapın. Liste gerçekten sabitse indeks kabul edilebilir olabilir; ancak ileride sıralama veya ekleme gelecekse baştan kalıcı ID kullanmak daha doğru temeldir.Kaynaklar
Sık sorulan sorular
key neden bileşene prop olarak ulaşmıyor?
Çünkü
key, React’in elemanları eşleştirmek için kullandığı özel bir özelliktir ve normal prop’lar gibi bileşene aktarılmaz. Bileşenin bu değere ihtiyacı varsa aynı değeri ayrı bir prop adıyla göndermelisiniz.key değişirse bileşen neden sıfırlanmış gibi görünür?
React yeni key’i farklı bir kimlik kabul eder. Bu nedenle önceki bileşenin yerel state’i ve yaşam döngüsü korunmaz; yeni bir bileşen oluşturulur. Bu davranış bazen formu bilinçli olarak sıfırlamak için kullanılabilir, ancak normal listelerde key’in kararlı tutulması gerekir.