Her render’da eklemek gerekir mi?
React performans optimizasyonu denince akla gelen iki hook var: useCallback ve useMemo.
Ama çoğu geliştirici bu ikisini “her render’da eklemek gerekir” sanıyor. Gerçek şu ki, bazen bu iki hook faydadan çok zarar bile verebilir.
Bu yazıda, ne işe yaradıklarını, ne zaman kullanılmaları gerektiğini ve yaygın yanlış anlamaları açıklıyoruz.
useCallback Nedir?
useCallback, bir fonksiyonun referansını değişmeden saklamak için kullanılır. React bileşenleri yeniden render edildiğinde, fonksiyonlar yeniden oluşturulur. Bu da child bileşenlerde gereksiz re-render’a yol açabilir.const handleClick = useCallback(() => {
console.log('Tıklama!')
}, [])
Bu sayede React aynı fonksiyon referansını korur, child bileşenler gereksiz yere yeniden render edilmez.Ne Zaman Kullanılır?
- Fonksiyon bir child component’e prop olarak geçiyorsa.
- O child
React.memo()ile optimize edilmişse. - Büyük listelerde, sık render olan yapılarda.
Ne Zaman Kullanılmaz?
- Fonksiyon sadece aynı component içinde kullanılıyorsa.
- render sıklığı düşükse.
- Performans kazancı ölçülmemişse.
useMemo Nedir?
useMemo, hesaplama sonucu değişmediği sürece sonucu önbelleğe alır. Yani pahalı işlemleri (ör. filtreleme, sıralama) her render’da yeniden çalıştırmaz.const sortedList = useMemo(() => {
return items.sort((a, b) => a.value - b.value)
}, [items])
Artık items değişmediği sürece sort işlemi tekrar çalışmaz.Ne Zaman Kullanılır?
- Büyük veri işlemleri (ör. tablolar, filtreler).
- Derived state hesaplamaları (ör. toplam, ortalama).
- render sırasında pahalı hesaplamalar yapılıyorsa.
Ne Zaman Kullanılmaz?
- Basit değer hesaplamaları.
- render maliyeti düşük bileşenlerde.
- Object veya array referansı önemli değilse.
useCallback ve useMemo Arasındaki Farklar
| Özellik | useCallback | useMemo |
|---|---|---|
| Ne saklar? | Fonksiyon referansı | Hesaplanan değer |
| Ne zaman çalışır? | Dependency değiştiğinde | Dependency değiştiğinde |
| Kullanım amacı | referans kararlılığı | hesaplama önbelleği |
| Dönen değer | Fonksiyon | Değer |
Gerçek Hayat Örneği
function ProductList({ products, onSelect }) {
const filtered = useMemo(() => products.filter(p => p.inStock), [products])
const handleClick = useCallback((id) => onSelect(id), [onSelect])
return (
<ul>
{filtered.map(p => (
<li key={p.id} onClick={() => handleClick(p.id)}>
{p.name}
</li>
))}
</ul>
)
}
Burada:useMemo→ stokta olan ürünleri hesaplamayı önbelleğe alır.useCallback→ tıklama fonksiyonunun referansını sabit tutar.
Yanlış Kullanım Örneği
const doubled = useMemo(() => value * 2, [value])
Bu tür hesaplamalar gereksizdir -- çünkü value * 2 zaten ucuz bir işlem. useMemo, hafıza ve GC (garbage collection) maliyeti ekler, yani ters etki yaratır.💡 Unutma: useMemo her zaman kazandırmaz; bazen fazladan yük getirir.
React.memo ile Kombinasyon
React.memo bir bileşeni prop referansları değişmedikçe yeniden render etmez. Ama fonksiyon prop’ları her render’da değişiyorsa bu işe yaramaz -- işte burada useCallback devreye girer.const Child = React.memo(({ onClick }) => {
console.log('Child render!')
return <button onClick={onClick}>Tıkla</button>
})
function Parent() {
const handleClick = useCallback(() => console.log('Tıklandı!'), [])
return <Child onClick={handleClick} />
}
Artık Parent her render olduğunda Child yeniden render edilmez. Performans farkı özellikle büyük listelerde hissedilir.useMemo ile Derin Hesaplamalar
useMemo, pahalı matematiksel işlemleri önbelleğe almak için de idealdir:const fibonacci = useMemo(() => calcFibonacci(40), [])
Ama dikkat! Eğer fonksiyon her render’da farklı bir dependency ile çağrılıyorsa, useMemo hiçbir işe yaramaz. 😊💡 Pro tip: Performans kazancı ölçülmeyen yerde useMemo ekleme. Profillemeden optimizasyon olmaz.
DevTools ile Ölçüm
React DevTools içinde “Profiler” sekmesiyle bileşenlerin render süresini ölçebilirsin. Gerçekten yavaşlayan component’lerdeuseMemo/useCallback işe yarar.Profiling Adımları:
- React DevTools → Profiler sekmesi.
- Interaksiyon oluştur (örneğin input yaz).
- Render sürelerini incele.
memoveuseCallbackekleyip farkı gözlemle.
Özet Tablo
| Amaç | Hook | Dikkat |
|---|---|---|
| Fonksiyon referansını sabitlemek | useCallback | Sadece prop olarak geçiyorsa kullan |
| Hesaplanan değeri önbelleğe almak | useMemo | Pahalı hesaplamalarda kullan |
| Component re-render’ını azaltmak | React.memo | Fonksiyon referansları değişmemeli |
Sonuç
useCallback ve useMemo, React’te mikro optimizasyon araçlarıdır -- her derde deva değil. Doğru kullanıldığında fark yaratır, yanlış kullanıldığında kodu karmaşıklaştırır.Kısaca:
useCallback→ Fonksiyon referansını korur.useMemo→ Hesaplama sonucunu cache’ler.React.memo→ Prop değişmedikçe re-render’ı engeller.