Değişiklik neden önemli
React, bir bileşeni yeniden render edip etmeyeceğine, önceki durum referansını yenisiyle karşılaştırarak karar verir. Eğer referans değişmemişse, React hiçbir şeyin değişmediğini varsayar. Klasik Array.prototype.sort yöntemi diziyi yerinde (in place) sıralar ve aynı referansı döndürür; bu nedenle setTasks(prev => prev.sort(fn)) gibi bir çağrı React'ın güncellemeyi fark edememesine neden olur. UI, güncel olmayan veride takılı kalır; bu, gerçek projelerde çok sık karşılaşılan bir hatadır.
Geliştiriciler, sıralama adımının yeni bir referans üretmesi için diziyi önce kopyalayarak (genellikle spread operatörü ile) bu sorunun etrafından dolanıyorlardı:
setTasks(prev => [...prev].sort((a, b) => b.priority - a.priority));
Bu desen işe yarar ancak gürültü yaratır ve unutulması kolaydır. Yeni ES2023 yöntemleri, orijinali bozmadan yeni bir dizi üretmenin doğrudan ve okunabilir bir yolunu sunar.
Mutasyona uğratmayan dört yöntem
toSorted(compareFn?)–sortgibi davranır ancak sıralanmış bir kopya döndürür. Kaynak dizi üzerinde değişiklik yapmaz.toReversed()–reverseyönteminin yerini alır. Orijinal sırayı bozmadan ters çevrilmiş bir kopya üretir.toSpliced(start, deleteCount, ...items)– Yan etkileri olmayan birspliceyansımasıdır. Döndürülen dizi ekleme veya çıkarma işlemini yansıtır, kaynak dizi aynı kalır.with(index, value)–indexkonumundaki öğeyivalueile değiştirir ve yeni bir dizi döndürür. Yaygın olanmapveya spread operatörü ile öğe değiştirme deseninin yerini alır.
Dört yöntemin tamamı ECMAScript standardının bir parçasıdır ve güncel ana tarayıcı sürümlerinde ve Node.js 20'de mevcuttur.
Kod artık nasıl görünüyor
Bir listeyi sıralama
// Before
setTasks(prev => [...prev].sort((a, b) => b.priority - a.priority));
// After
setTasks(prev => prev.toSorted((a, b) => b.priority - a.priority));
Tek bir öğeyi güncelleme
// Before
setItems(prev =>
prev.map((item, i) => (i === idx ? newItem : item))
);
// After
setItems(prev => prev.with(idx, newItem));
Bir diziyi ters çevirme
setLogs(prev => prev.toReversed());
Bir öğeyi kaldırma
setTags(prev => prev.toSpliced(removeIdx, 1));
Yeni sözdizimi, ekstra spread operatörlerine veya eşleme (mapping) döngülerine olan ihtiyacı ortadan kaldırarak durum güncellemelerini okumayı kolaylaştırır ve hata payını azaltır.
Kimler faydalanır ve kimler tereddüt edebilir
React, Vue, Redux, Zustand veya değişmez (immutable) veri yapıları bekleyen herhangi bir framework kullanan geliştiriciler, daha net bir zihinsel model kazanır: bir yöntemi çağır, yeni bir dizi al ve bunu setter'a geri ver. Gereksiz kodun (boilerplate) azalması, motorun sıralamadan önce ara bir kopya oluşturmaktan kaçınması sayesinde render döngülerinden birkaç milisaniye bile kazanabilir.
Eski tarayıcıları kullanan ekipler, polyfill eklemek zorunda kalabilir. Bu yöntemler Safari veya Internet Explorer'ın eski sürümlerinde bulunmadığından, bu platformları hedefleyen bir üretim (production) sürümü bir fallback (yedek plan) içermelidir. Bu, paket boyutunda küçük bir artışa neden olur ancak sağlanan okunabilirlik kazancı genellikle bu farka değer.
Kütüphane yazarları, yeni imzaları (signatures) dışarıya açmak için tip tanımlarını (örneğin TypeScript) güncellemek zorunda kalabilir. Bu tanımlar resmi @types paketlerine gelene kadar geliştiriciler geçici tip hatalarıyla karşılaşabilir.
Sırada ne var?
- Benimsenme metrikleri – ESLint gibi araçlar, yakında durum setter'larındaki değiştirilebilir (mutable) dizi çağrılarını işaretleyen ve geliştiricileri yeni yöntemlere yönlendiren kurallar ekleyebilir.
- Performans çalışmaları – İlk kıyaslamalar (benchmarks), yerleşik mutasyona uğratmayan yöntemlerin, bir spread operatörü kopyalaması ve ardından gelen değiştirilebilir bir işlemden daha hızlı olduğunu gösteriyor; ancak gerçek dünya verileri bu etkiyi doğrulayacaktır.
- Daha fazla öneri – ECMAScript komitesi, varsayılan olarak değişmez (immutable-by-default) API'leri keşfetmeye devam ediyor; gelecek aşamaları takip etmek, aynı desene uyan daha fazla yardımcı yöntemin ortaya çıkmasını sağlayabilir.
Özet
En son ECMAScript spesifikasyonu, UI geliştiricilerine, sayısız hataya neden olan spread operatörü jimnastiğine gerek kalmadan durumu değişmez tutmanın yerleşik ve özlü bir yolunu sunuyor. sort, reverse, splice ve indeks tabanlı değişimleri toSorted, toReversed, toSpliced ve with ile değiştirerek, React'ın değişiklik algılama mekanizmasının amaçlandığı gibi çalışmasını sağlar ve kodunuzu daha okunabilir hale getirirsiniz. Hedef tarayıcılarınız yeni yöntemleri destekliyorsa —veya onları polyfill etmeye hazırsanız— eski desenleri emekli etme ve işin ağır kısmını dile bırakma zamanı gelmiştir.
