useCallback — temel kavramlar, React'te işlev bellekleme hook'u

Yazar: IT Sectr Yayınlanma: 2026-07-04 Okuma süresi: 9 dk

useCallback, bağımlılıkları değişene kadar oluşturmalar arasında değişmeyen bir işlevin belleğe alınmış sürümünü döndüren bir React hook'udur. Bir bileşen içindeki normal işlev bildiriminin (her oluşturmada yeni bir işlev oluşturur) aksine, useCallback işlev referansını stabilize ederek React.memo ile optimize edilmiş alt bileşenlerin gereksiz yeniden oluşturulmasını önler. React Documentation (2025)'a göre, useCallback yalnızca React.memo veya kararlı bir referansa bağlı hook'larla birlikte kullanıldığında faydalıdır.

Önemli Noktalar

  • useCallback — bir işlevi belleğe almak için hook, oluşturmalar arasında referansı korur.
  • React.memo — useCallback yalnızca React.memo ile yeniden oluşturmayı önlemede etkilidir.
  • Bağımlılıklar — işlev yalnızca dizide belirtilen değerler değiştiğinde yeniden oluşturulur.
  • Kararlı referans — useCallback, işlev referansının gereksiz yere değişmeyeceğini garanti eder.
  • Aşırı kullanmayın — React.memo olmadan aşırı useCallback performansı düşürür.

React'te useCallback Nedir

useCallback, React 16.8'de eklenen ve bir işlevi belleğe alan bir hook'tur: bağımlılıklar değişene kadar aynı referansı döndürür. useCallback olmadan, bir bileşen içindeki her işlev bildirimi her oluşturmada yeni bir işlev nesnesi oluşturur. İlkeller için bu fark edilmez, ancak bu callback'leri React.memo ile optimize edilmiş alt bileşenlere iletirken, her yeni referans alt bileşenin yeniden oluşturulmasına neden olur.

Sözdizimsel olarak, useCallback bir işlev için useMemo'ya eşdeğerdir: useCallback(fn, deps), useMemo(() => fn, deps) için kısa yoldur. React, belleğe alınmış işlevi fiber düğümünün dahili deposunda tutar ve her oluşturmada bağımlılıkları karşılaştırır. Bağımlılıklar değişmemişse (her öğe için Object.is), önceki işlev döndürülür.

React Documentation — useCallback (2025)'a göre, her işlevi useCallback ile sarmamalısınız. Hook'un kendi maliyeti vardır: hook'u çağırma, bağımlılıkları karşılaştırma ve bağımlılık dizisi için bellek ayırma. Bir bileşen basitse ve React.memo ile derin ağaçları yoksa, useCallback yalnızca uygulamayı yavaşlatır. Optimizasyon ölçülebilir olmalı, sezgisel değil.

jsx
import { useCallback } from 'react';

function Parent() {
    const [count, setCount] = useState(0);

    // Kararlı referans — deps değişene kadar aynı işlev
    const handleClick = useCallback(() => {
        setCount(prev => prev + 1);
    }, []);

    return <Child onClick={handleClick} />;
}

İşlev Bellekleme Nasıl Çalışır

useCallback içindeki bellekleme, işlev çağrısının sonucunu önbelleğe almaya dayanır. React, ilk oluşturma sırasında oluşturulan kapanımı (closure) korur ve bağımlılıklar değişmediği sürece sonraki oluşturmalarda onu döndürür. Fiber düğümü içinde, her useCallback çağrısı, önceki bağımlılıkların ve belleğe alınmış değerin depolandığı hook'ların bağlantılı listesinde bir düğüm oluşturur.

Bağımlılık karşılaştırması kesinlikle Object.is aracılığıyla yapılır — nesnelerin veya dizilerin derinlemesine kontrolü olmadan yüzeysel bir karşılaştırma. Bir bağımlılık bir nesne veya dizi ise, her oluşturmada yeni bir referans değişiklik olarak kabul edilir. Bu nedenle, bağımlılık dizisi ilkel değerler veya kararlı referanslar (örneğin, useRef veya useMemo'dan) içermelidir.

React Core Team — Optimization Guide (2024)'e göre, belleklemenin maliyeti üç bileşen içerir: her oluşturmada bağımlılık dizisi ayırma, Object.is aracılığıyla öğeleri yineleme ve karşılaştırma ve yeniden oluşturma sırasında potansiyel çöp toplama yükü. Yüzlerce useCallback sarmalayıcısı olan bir bileşen için bu fark edilebilir hale gelebilir — bu nedenle hook kullanımında seçicilik çok önemlidir.

SenaryouseCallback OlmadanuseCallback ile
İşlev oluşturmaHer oluşturmada yeniKararlı deps ile aynı
React.memo'ya aktarmaAlt yeniden oluşturulurAlt yeniden oluşturulmaz
useEffect dizisindeEfekt yeniden başlarEfekt kararlı
YükMinimumBağımlılık karşılaştırması + bellek

useCallback ve Performans

useCallback'in otomatik olarak performansı artırdığına dair yaygın bir yanlış kanı vardır. Gerçekte, tek başına (React.memo olmadan), useCallback bağımlılık karşılaştırma maliyeti nedeniyle uygulamayı biraz yavaşlatır. Hook yalnızca üç senaryoda gerçek fayda sağlar: React.memo bileşenlerinin yeniden oluşturulmasını önleme, useEffect'te callback'leri kararlı hale getirme ve referans eşitliğine bağlı özel hook'lara callback aktarma.

Kural basittir: React DevTools Profiler ile bir performans sorunu tespit edene kadar useCallback kullanmayın. React ekibi, erken optimizasyonun tüm kötülüklerin kaynağı olduğunu defalarca vurgulamıştır. Önce bellekleme olmadan temiz kod yazın, ölçün, profil oluşturucuda darboğazı bulun ve ancak o zaman gerçekten gerekli yerlere useCallback ekleyin.

jsx
// Ölçülebilir optimizasyon: Child, React.memo ile sarılmış
const Child = React.memo(({ onClick }) => {
    console.log('Child yeniden oluşturuldu');
    return <button onClick={onClick}>Click</button>;
});

function Parent() {
    const handleClick = useCallback(() => {
        console.log('tıklandı');
    }, []);
    return <Child onClick={handleClick} />;
}

Dan Abramov — Before You memo() (2024)'e göre, açık kaynak projelerde useCallback kullanımının %90'ından fazlası gereksizdir. Geliştiriciler, etkiyi ölçmeden "her ihtimale karşı" her işlevi sararlar. Alternatif: alt bileşen ağırsa ve yeniden oluşturulması pahalıysa — React.memo + useCallback haklıdır. Alt bileşen hafifse — yeniden oluşturma, bağımlılık karşılaştırmasından daha ucuzdur.

useCallback Ne Zaman Kullanılmalı

İlk senaryo React.memo'dur. Bir alt bileşen React.memo ile sarılmışsa ve bir prop olarak callback işlevi alıyorsa, useCallback olmadan alt bileşen, kendi verileri değişmemiş olsa bile her üst oluşturmada yeniden oluşturulur. useCallback referansı kararlı hale getirir ve React.memo'nun yeniden oluşturmayı doğru şekilde atlamasını sağlar.

İkinci senaryo, bağımlılıklarda callback ile useEffect'tir. Bir işlev useEffect bağımlılık dizisine aktarılırsa, her yeni referans efekti yeniden başlatır. useCallback, referansın kararlı olmasını ve efektin yalnızca gerçek veriler değiştiğinde çalışmasını sağlar, her oluşturmada değil. Bu, özellikle abonelikler ve istekler için önemlidir.

  • React.memo alt öğeleri — callback iletirken belleğe alınmış alt bileşenlerin yeniden oluşturulmasını önler.
  • useEffect bağımlılıkları — efekt bağımlılık dizisindeki işlevi kararlı hale getirir, gereksiz yeniden başlatmaları önler.
  • Özel hook'lar — bir hook bir callback kabul ediyorsa ve referans eşitliğine bağlıysa, useCallback zorunludur.
  • Bağlam değeri — bağlam değerinde bir işlev aktarılırsa, useCallback referansı kararlı hale getirir.
jsx
// Kararlı useEffect bağımlılığı için useCallback
const fetchData = useCallback(async (id) => {
    const res = await fetch(`/api/${id}`);
    setData(res.data);
}, []); // kararlı referans, asla yeniden oluşturulmaz

useEffect(() => {
    fetchData(props.id);
}, [props.id, fetchData]); // efekt yalnızca props.id değiştiğinde çalışır

useCallback vs useMemo

useCallback ve useMemo arasındaki temel fark, her birinin neyi belleğe aldığıdır. useCallback bir işlevi belleğe alır: useCallback(fn, deps), fn'i (aynısı veya önceki sürümü) döndürür. useMemo bir işlev çağrısının sonucunu belleğe alır: useMemo(() => computeExpensive(a, b), [a, b]) hesaplanan değeri döndürür, bir işlevi değil.

Teknik olarak, useCallback, useMemo üzerinde sözdizimsel şekerdir: useCallback(fn, deps), useMemo(() => fn, deps) ile eşdeğerdir. Bu sözdizimi yalnızca okunabilirlik için vardır — geliştiricinin bir değer değil, bir işlevin belleğe alındığını açıkça görmesi için. useCallback ve bir işlevle useMemo arasında performans farkı yoktur — aynı kodu üretirler.

HookBelleğe alırSözdizimiKullanım
useCallbackİşlev (referans)useCallback(fn, deps)Alt bileşenler için callback'ler
useMemoHesaplama sonucuuseMemo(() => value, deps)Pahalı hesaplamalar, nesne bellekleme
jsx
// Bunlar eşdeğerdir:
const handleClick = useCallback(() => doSomething(a, b), [a, b]);
const handleClick = useMemo(() => () => doSomething(a, b), [a, b]);

useCallback ile Sık Yapılan Hatalar

En yaygın hata, alt bileşenlerde React.memo olmadan tüm işlevleri useCallback ile anlamsızca sarmaktır. Bir alt bileşen React.memo ile sarılmamışsa, callback referansı değişsin veya değişmesin, her üst oluşturmada yine de yeniden oluşturulur. React.memo olmadan useCallback — faydasız maliyettir.

  • React.memo olmadan useCallback — alt bileşen yine de yeniden oluşturulur; optimizasyon anlamsızdır.
  • Unutulan bağımlılıklar — callback içinde kullanılan bir değişken deps'te yoksa, callback eski kapanım (stale closure) içerir.
  • Aşırı bellekleme — console.log ile önemsiz onClick dahil her işlevi sarmak.
  • Bağımlılıklarda nesneler ve diziler — her oluşturmada yeni bir referans değişiklik olarak kabul edilir, bellekleme işe yaramaz.
jsx
// ❌ Yararsız: alt öğede React.memo yok
const handle = useCallback(() => doStuff(), []);
<Child onClick={handle} />; // Child, React.memo olmadan yine de yeniden oluşturulur

// ❌ Eski kapanım: eksik bağımlılık
const handle = useCallback(() => {
    console.log(count); // count her zaman 0 — eski kapanım!
}, []);

// ✅ Doğru: bağımlılıkları dahil et
const handle = useCallback(() => {
    console.log(count);
}, [count]);

useCallback'teki eski kapanım (stale closure) sorunu, kullanılan tüm değişkenlerin bağımlılık dizisine dahil edilmesiyle çözülür. exhaustive-deps ile eslint-plugin-react-hooks, callback gövdesindeki tüm değişkenlerin dizide mevcut olup olmadığını otomatik olarak kontrol eder. Callback, oluşturmalar arasında değişmeyen setState'i kullanıyorsa, güvenle deps'e dahil edilebilir — React, setState'in kararlılığını garanti eder.

Sıkça Sorulan Sorular

Her işlev useCallback ile sarılmalı mı?

Hayır. useCallback yalnızca üç durumda anlamlıdır: alt bileşen React.memo ile sarılmışsa, işlev useEffect bağımlılık dizisinde kullanılıyorsa veya işlev referans eşitliğine bağlı özel bir hook'a aktarılıyorsa. Diğer durumlarda, useCallback faydasız yük ekler. React ekibi, önce optimizasyon olmadan yazmayı ve profil oluşturma sonuçlarına göre eklemeyi önerir.

Hangisi daha hızlı — useCallback mi yoksa her oluşturmada yeni işlev mi?

Basit bileşenler için — her oluşturmada yeni işlev biraz daha hızlıdır, çünkü useCallback bağımlılıkları karşılaştırmak ve dizi ayırmak için kaynak harcar. Derin React.memo ağaçları olan bileşenler için useCallback, binlerce alt öğenin yeniden oluşturulmasını önleyerek kazanır. Tahmin etmek yerine ölçün ve karşılaştırın — objektif değerlendirme için React DevTools Profiler kullanın.

useCallback async işlevlerle kullanılabilir mi?

Evet, useCallback async işlevlerle senkron işlevlerle tamamen aynı şekilde çalışır. Hook, işlevin kendisini belleğe alır ve sonuç (bir Promise) her çağrıldığında döndürülür. useCallback içindeki bir async işlev, useEffect'te kullanılan kararlı veri yükleme callback'leri için yaygın bir kalıptır: const fetchData = useCallback(async (id) => {...}, []).

useCallback ve React.memo ile ilgili sorunlar nasıl hata ayıklanır?

React DevTools Profiler kullanın — hangi bileşenlerin yeniden oluşturulduğunu ve nedenini gösterir. Programatik kontrol için, console.log ekleyin veya useWhyDidYouUpdate kullanın — yeniden oluşturma nedenini günlükleyen bir kütüphane. Ana nedenler: bir prop değişti (callback referansı dahil), durum değişti veya bağlam değişti. useCallback yardımcı olmazsa — tüm bağımlılıkların doğru şekilde belirtildiğini kontrol edin.

React.memo olmadan alt bileşene useCallback nasıl aktarılır?

React.memo olmasa bile, useCallback bağlam değerleri için useMemo ile kombinasyon halinde yararlı olabilir. Context.Provider'a işlevleri olan bir nesne aktarıyorsanız, nesne oluşturmayı useMemo'ye ve her işlevi useCallback'e sarın. Bu, işlevlerden biri değiştiğinde tüm bağlam tüketicilerinin yeniden oluşturulmasını önler. Ancak React.memo olmadan doğrudan props'ta callback'leri iletmek için useCallback'in faydası yoktur.

Özet

  • useCallback — bir işlevi belleğe alan hook, bağımlılıklar değişene kadar kararlı referans döndürür.
  • React.memo sinerjisi — useCallback yalnızca alt bileşenlerde React.memo ile etkilidir.
  • Bağımlılık karşılaştırması — Object.is aracılığıyla; deps'teki nesneler/diziler bellekleme bozar.
  • Ölçün, tahmin etmeyin — profil oluşturucuda darboğaz tespit ettikten sonra useCallback ekleyin.
  • Kararlı kapanım — kullanılan tüm değişkenleri bağımlılık dizisine dahil edin, aksi takdirde — eski kapanım.
  • useCallback vs useMemo — useCallback bir işlevi belleğe alır, useMemo bir hesaplama sonucunu belleğe alır.
  • Aşırı kullanım — gerçek projelerde useCallback kullanımının %90'ından fazlası erken optimizasyondur.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun