React'te useRef hook'u çoğu geliştirici tarafından yalnızca DOM elementlerine erişmek için kullanılsa da aslında çok daha geniş bir kullanım yelpazesine sahiptir. Bu yazıda useRef'in bilinmeyen yönlerini, ne zaman ve nasıl kullanmanız gerektiğini adım adım inceleyeceğiz. Özellikle performans odaklı React uygulamalarında useState yerine useRef tercih etmeniz gereken senaryoları ve dikkat edilmesi gereken noktaları ele alacağız.
useRef Nedir ve Ne Zaman Kullanılır?
useRef, React'te bir referans nesnesi döndüren ve bu nesnenin .current özelliği üzerinden değişken değerleri saklamanıza olanak tanıyan bir hook'tur. useRef ile saklanan değerler bileşen yeniden render edildiğinde korunur, ancak değer değiştiğinde yeniden render tetiklenmez. Bu özellik, onu özellikle aşağıdaki durumlar için ideal kılar:
- DOM elementlerine doğrudan erişim (focus, ölçüm alma)
- Render döngüsü boyunca korunması gereken ancak değişikliği render tetiklememesi gereken değişkenler
- Üçüncü parti kütüphanelerle entegrasyon (harita, grafik)
- Interval, timeout ID'lerini saklama
- Önceki state veya props değerlerini tutma
useRef ile DOM Manipülasyonu: Temel Kullanım
useRef'in en yaygın kullanımı, bir DOM elementine referans alarak doğrudan müdahale etmektir. Örneğin, bir input'a otomatik focus vermek için:
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} />;
Bu yöntem, React'te Intersection Observer ile sonsuz kaydırma gibi senaryolarda da kullanılabilir. Ancak unutmayın: ref ile DOM'a erişmek, React'in deklaratif yapısını bozan bir kaçış yolu olduğu için yalnızca zorunlu durumlarda tercih edilmelidir.
useRef ile Değişken Saklama: Render Tetiklemeden Veri Tutma
useRef'in en güçlü ama az bilinen özelliklerinden biri, bileşen yeniden render edilse bile değerini koruyan ancak render tetiklemeyen bir değişken olarak kullanılmasıdır. Örneğin, bir sayaç değerini render tetiklemeden artırmak istiyorsanız:
const countRef = useRef(0);
const handleClick = () => {
countRef.current += 1;
console.log(countRef.current);
};
Bu sayede state değişikliği gerektirmeyen veriler (örneğin, kullanıcının sayfada geçirdiği süre, scroll pozisyonu) için useState yerine useRef kullanarak gereksiz render'ları önleyebilirsiniz. Bu, offline web uygulamaları gibi performans kritik projelerde önemli bir optimizasyon sağlar.
useRef ile Önceki State/Props Değerlerini Saklama
React'te bir önceki state veya props değerine ihtiyaç duyduğunuzda, bunu bir ref içinde saklayabilirsiniz. useEffect ile ref'i güncelleyerek karşılaştırma yapabilirsiniz:
const [count, setCount] = useState(0);
const prevCountRef = useRef();
useEffect(() => {
prevCountRef.current = count;
});
const prevCount = prevCountRef.current;
Bu desen, özellikle animasyonlar, geçiş efektleri veya değişimleri izleme gibi durumlarda işe yarar. Örneğin, bir liste öğesinin yeni eklendiğini veya silindiğini tespit etmek için kullanabilirsiniz.
useRef ile Performans İyileştirme: Callback ve Interval'ları Yönetme
useRef, setInterval ve setTimeout gibi API'lerin ID'lerini saklamak için mükemmeldir. Bu sayede bileşen unmount olduğunda temizlik yapabilir veya interval'i durdurabilirsiniz:
const intervalRef = useRef();
const startInterval = () => {
intervalRef.current = setInterval(() => {
console.log('Tick');
}, 1000);
};
const stopInterval = () => {
clearInterval(intervalRef.current);
};
useEffect(() => {
return () => clearInterval(intervalRef.current);
}, []);
Ayrıca, useRef ile callback fonksiyonlarını saklayarak gereksiz render'ları önleyebilirsiniz. Özellikle cursor-based pagination gibi asenkron veri çekme işlemlerinde, en güncel callback'i ref içinde tutmak, closure problemlerini çözer.
useRef ve Forward Ref: Bileşenler Arası Ref Paylaşımı
Bir alt bileşenin DOM'una üst bileşenden erişmek için React.forwardRef() ile ref'i iletebilirsiniz. Örneğin, özel bir input bileşeni:
const CustomInput = React.forwardRef((props, ref) => (
<input ref={ref} {...props} />
));
// Üst bileşen:
const inputRef = useRef();
<CustomInput ref={inputRef} />;
Bu yöntem, kütüphane geliştirirken veya form kütüphaneleriyle çalışırken sıkça kullanılır. Unutmayın: forwardRef yalnızca fonksiyonel bileşenlerle çalışır; sınıf bileşenlerinde ref prop'u otomatik olarak çalışmaz.
useRef Kullanırken Sık Yapılan Hatalar
- useRef'i state yerine kullanmak: useRef değişikliği render tetiklemez. Eğer değer değişikliğinin UI'a yansımasını istiyorsanız useState kullanmalısınız.
- Ref'i useEffect içinde güncellemek: Ref değişikliği render tetiklemediği için useEffect bağımlılık listesine ref'i eklemek anlamsızdır. Ref'i doğrudan event handler'da veya useCallback içinde güncelleyin.
- Ref'i her render'da sıfırlamak: useRef bileşenin tüm yaşam döngüsü boyunca aynı referansı korur. Bu nedenle ref'i useState gibi düşünmeyin, başlangıç değerini yalnızca ilk render'da atayın.
- Forward ref kullanmamak: Özel bir bileşenin ref prop'unu doğrudan DOM elementine bağlamak için forwardRef kullanmak gerekir. Aksi halde ref, bileşenin kendisine bağlanır.
Sonuç: useRef'i Doğru Kullanmak Performansı Artırır
useRef, React'in en basit ama en güçlü hook'larından biridir. DOM manipülasyonu, değişken saklama, önceki değerleri tutma ve performans optimizasyonu gibi alanlarda size büyük esneklik sağlar. Ancak unutmayın: useRef'i yalnızca gerçekten ihtiyacınız olduğunda kullanın. Render tetiklemesi gereken durumlarda state kullanmaya devam edin. Doğru kullanıldığında, uygulamanızın performansını gözle görülür şekilde iyileştirebilir ve daha temiz bir kod yapısı oluşturabilirsiniz.
Sık Sorulan Sorular
useRef ile useState arasındaki temel fark nedir?
useRef değeri değiştiğinde bileşenin yeniden render edilmesine neden olmaz, oysa useState değer değiştiğinde render'ı tetikler. Bu nedenle, UI'a yansıması gerekmeyen verileri saklamak için useRef tercih edilir.
useRef ile DOM elementine nasıl erişirim?
Öncelikle useRef(null) ile bir ref nesnesi oluşturun, ardından erişmek istediğiniz DOM elementine ref={refAdi} prop'u olarak atayın. Sonrasında refAdi.current ile elemente erişebilirsiniz.
forwardRef ne zaman kullanılmalıdır?
Bir üst bileşenin, alt bileşenin DOM'una erişmesi gerektiğinde forwardRef kullanılır. Özellikle özel input, buton gibi bileşenlerde ref'i iletmek için gereklidir.
useRef ile interval ID'sini saklamak neden önemlidir?
Interval ID'sini ref içinde saklamak, bileşen unmount olduğunda temizlik yapmayı (clearInterval) kolaylaştırır ve aynı interval'in birden fazla kez başlatılmasını önler.
useRef performansı nasıl artırır?
useRef gereksiz render'ları engeller. Örneğin, bir sayaç değerini useState yerine useRef'te tutarak her tıklamada render'ı tetiklemezsiniz. Ayrıca callback'leri ref'te saklayarak closure sorunlarını çözebilir ve yeniden render'ları azaltabilirsiniz.






