useRef, .current özelliğine sahip değiştirilebilir bir ref nesnesi oluşturan ve bileşenin render'ları arasında korunan bir React hook'udur. useState'in aksine, .current'ı değiştirmek yeniden render'a neden olmaz, bu da useRef'i DOM referanslarını, zamanlayıcıları ve UI'ı yeniden çizmeden render'lar arasında kalıcı olması gereken değerleri depolamak için ideal hale getirir. React Dokümantasyonu (2025)'na göre, ref nesnesi bileşenin ömrü boyunca bir kez oluşturulur ve render'lar arasında değişmez, referans kararlılığını garanti eder.
Önemli noktalar
useRef, React 16.8'de eklenen ve tek bir .current özelliğine sahip değiştirilebilir bir ref nesnesi döndüren bir hook'tur. İlk değer, bileşen monte edildiğinde .current'a atanır. Normal bir değişkenden temel farkı, ref nesnesinin yeniden render'lardan sağ çıkmasıdır: sonraki render'larda React ref'i yeniden oluşturmaz, aynı nesneyi döndürür.
Dahili olarak, useRef useState ve useEffect ile aynı mekanizmayı kullanır — fiber düğümünde hook'ların bağlantılı listesi. Ancak useState'ten farklı olarak, React ref nesnesindeki değişiklikleri izlemez, güncellemeleri sıraya koymaz ve yeniden render planlamaz. Bu, useRef'i sık değişikliklerde bile performansı etkilemeyen son derece hafif bir hook yapar.
React Ekibi — Hooks SSS (2025)'ne göre, useRef temel olarak bir değer depolayan bir “kutu”dur. Sözdizimsel şeker: const ref = useRef(başlangıçDeğeri), const ref = { current: başlangıçDeğeri } ile eşdeğerdir, ancak React'in ref nesnesinin her render'da aynı olacağını garanti etmesi farkıyla. Sihir yok — sadece React tarafından yönetilen kararlı bir referans.
import { useRef } from 'react';
function Component() {
const countRef = useRef(0);
// countRef.current = 0 başlangıçta
// countRef.current = 5 değişiklikten sonra
// Yeniden render olmaz!
}
useRef'in en yaygın kullanım durumu, bir DOM öğesine doğrudan erişim sağlamaktır. React, bileşen monte edildikten sonra elementRef.current'e DOM düğümüne bir referans atar. Bu, bir girdiyi odaklamak, öğe boyutlarını ölçmek, animasyon kütüphaneleri ve React render'ını kullanmayan kütüphanelerle entegrasyon için gereklidir.
React, DOM'daki ref referanslarını otomatik olarak yönetir: monte ederken gerçek DOM düğümünü atar, monte etme işlemini kaldırırken null yapar. Bu, .current'ın her zaman güncel değeri tutmasını garanti eder ve kaldırılan öğelere asılı referanslar yoluyla bellek sızıntılarını önler. Manuel temizlik gerekmez.
function AutoFocusInput() {
const inputRef = useRef(null);
useEffect(() => {
// Bileşen monte edildikten sonra girdiyi odakla
inputRef.current?.focus();
}, []);
return <input ref={inputRef} type="text" />;
}
React — Refs ve DOM dokümantasyonu (2025)'na göre, bildirimsel işlemler için ref kullanmayın — modal açma/kapama, görünürlük yönetimi. Bu amaçlar için state ve props vardır. Refs, bildirimsel olarak ifade edilemeyen zorunlu işlemler içindir: odaklama, metin seçimi, üçüncü taraf kütüphanelerle entegrasyon.
İkinci en önemli kullanım durumu, render'lar arasında kalıcı olması gereken ancak değişikliklerinin yeniden render'ı tetiklememesi gereken rastgele değerleri depolamaktır. Tipik örnekler: zamanlayıcı tanımlayıcıları (setInterval/setTimeout), istek iptal bayrakları, karşılaştırma için önceki prop değerleri ve UI çıktısını etkilemeyen herhangi bir veri.
Bu özellikle useEffect'te kullanışlıdır: useRef zamanlayıcı tanımlayıcısını depolar ve temizlik onu siler. timerId useState'te depolanmış olsaydı, her setTimerId çağrısı ne mantık ne de UI için gereksiz bir yeniden render'a neden olurdu. useRef bu sorunu ek yük olmadan ve gereksiz yeniden render'lar olmadan çözer.
function Timer() {
const intervalRef = useRef(null);
const start = () => {
intervalRef.current = setInterval(() => {
console.log('tik');
}, 1000);
};
const stop = () => {
clearInterval(intervalRef.current);
};
useEffect(() => stop, []);
return <><button onClick={start}>Start</button><button onClick={stop}>Stop</button></>;
}
Temel ikilem — useRef ve useState arasında seçim yapmak — tek bir soruyla çözülür: “Değer değiştiğinde yeniden render gerekli mi?”. Evet ise — useState. Hayır ise — useRef. useState, bileşen çıktısını etkileyen durumu depolar; useRef, dahili mantık için gerekli ancak UI'yı etkilemeyen verileri depolar.
Pratikte, geliştiriciler kapanım sorunlarından kaçınmak için geri çağrıları depolamak amacıyla useRef'i sıklıkla kullanır. Örneğin, useEffect bir olaya abone oluyorsa ve geri çağrının mevcut duruma ihtiyacı varsa — geri çağrıyı useRef'te saklayın. Her render'da ref.current'i yeni bir işlevle güncelleyin ve efekt, yeniden abone olmadan her zaman taze geri çağrıyı çağıracaktır.
| Kriter | useRef | useState |
|---|---|---|
| Yeniden render | Değişiklikte tetiklemez | Her setState'te tetikler |
| Değişiklik | Doğrudan: ref.current = değer | Setter aracılığıyla: setState(değer) |
| JSX'te kullanım | Kullanılmaz (etkisi yok) | Bileşen çıktısında kullanılır |
| Örnek | Zamanlayıcılar, DOM referansları, önceki değerler | Form verileri, UI durumu, bayraklar |
Bir anti-kalıp vardır: JSX'te gerekli olan ancak değişikliklerinin yeniden render'a neden olmaması gereken veriler için useRef kullanmak. Bu, eşitsizliğe yol açar — UI eski verileri gösterirken ref.current zaten yenidir. Değer UI'da görüntüleniyorsa — useState kullanın. Yalnızca dahili olarak kullanılıyorsa — useRef.
useRef + useEffect kombinasyonu, önceki prop değerlerini izlemek için standart kalıptır. Önceki değeri ref'te saklayın, useEffect'te mevcut değerle karşılaştırın ve farka dayalı kararlar alın. Bu, değişiklikten önce değerin ne olduğunu bilmeniz gereken animasyonlarda özellikle kullanışlıdır.
function PriceDisplay({ price }) {
const prevPriceRef = useRef(price);
useEffect(() => {
const prevPrice = prevPriceRef.current;
if (price > prevPrice) {
animateUp();
} else if (price < prevPrice) {
animateDown();
}
prevPriceRef.current = price;
}, [price]);
return <span>${price}</span>;
}
React Dokümantasyonu — Hooks SSS (2025)'ne göre, bu kalıba “önceki değer kalıbı” denir. Çalışır çünkü useRef değeri render'lar arasında korur ve useEffect değişiklikler onaylandıktan sonra yürütülür. Önce DOM yeni fiyatla güncellenir, ardından useEffect onu (hâlâ ref'te olan) öncekiyle karşılaştırır ve ref.current'ı mevcut değere günceller.
En sık yapılan hata, JSX hesaplamak için render aşamasında ref.current'ı okumaktır. ref.current'ı değiştirmek yeniden render'ı tetiklemediğinden, bileşen güncel olmayan bir değer kullanabilir. .current UI çıktısına katılıyorsa — useState kullanın. Ref ve state'i senkronize etmeniz gerekiyorsa, state'i ref'ten güncellemek için useEffect kullanın.
// ❌ Görüntüleme için render sırasında ref.current'ı okumayın
function BadComponent() {
const valRef = useRef(0);
return <p>{valRef.current}</p>; // değişiklikte güncellenmeyecek
}
// ✅ Görüntüleme için state, mantık için ref kullanın
function GoodComponent() {
const [val, setVal] = useState(0);
const valRef = useRef(0);
return <p>{val}</p>;
}
Bir diğer yaygın hata, verilerin aslında UI'yı etkilediği bir bileşende durumu depolamanın tek yolu olarak useRef kullanmaktır. Geliştiriciler “gereksiz” yeniden render'lardan kaçınmak için useRef'i seçer, ancak sonuçta güncellenmeyen bir UI elde ederler. Doğru yaklaşım: UI verileri için useState ve yalnızca render'a katılmayan yardımcı değerler için useRef kullanın.
Sıkça sorulan sorular
Evet, bu yaygın bir kalıptır — önceki durum kalıbı. Bir ref oluşturun ve izlenen değer her değiştiğinde useEffect'te güncelleyin. Render ve efekt arasında, ref.current önceki değeri içerir ve bu, mevcut olanla karşılaştırılabilir. Bu ek yeniden render gerektirmez ve herhangi bir veri türüyle çalışır.
React, ref.current'e DOM düğümü değerini yalnızca öğe render edilip gerçek DOM'a eklendikten sonra atar. İlk render sırasında bileşen henüz monte edilmemiştir, bu nedenle ref.current başlangıç değerine (null) eşittir. ref.current aracılığıyla DOM'a erişim yalnızca useEffect'te veya montajdan sonra çağrılan olay işleyicilerinde mümkündür.
createRef her render'da yeni bir ref nesnesi oluşturur — yalnızca sınıf bileşenlerinde kullanılmalıdır. useRef ref'i bir kez oluşturur ve sonraki tüm render'larda aynı nesneyi döndürür. İşlevsel bileşenlerde yalnızca useRef kullanın; createRef, nesne yeniden oluşturulacağından yeniden render'da değer kaybına neden olur.
Evet, bir ref nesnesi normal bir prop olarak aktarılabilir: <Child inputRef={inputRef} />. Alt bileşen, inputRef.current aracılığıyla kullanır. Ancak, bir ref'i doğrudan bir alt bileşenin DOM öğesine aktarmak için forwardRef kullanın — props aracılığıyla ref'leri yönlendirmeye izin veren bir HOC. forwardRef olmadan, ref alt bileşenin içindeki DOM öğesine otomatik olarak bağlanmaz.
Öğeye bir ref bağlayın, ardından useEffect'te ref.current.getBoundingClientRect() veya ref.current.offsetWidth / offsetHeight okuyun. Boyut değişikliklerinin reaktif takibi için useEffect içinde ResizeObserver kullanın: bir observer oluşturun, değişikliklere abone olun ve state'i yeni boyutlarla güncelleyin. Temizlikte observer'ın bağlantısını kesmeyi unutmayın.
Özet
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.
Ayrıca okuyun