Today I Truly Understood the useRef Hook (Not Just What It Does, But Why It Exists)
Mevcut Sayı: {count}
Today I Truly Understood the useRef Hook (Not Just What It Does, But Why It Exists)
React geliştiricilerinin yolculuğunda, useState ve useEffect gibi hook’lar genellikle ilk öğrenilen ve en sık kullanılan araçlardır. Ancak useRef hook’u, ilk bakışta sadece DOM elementlerine erişmek için basit bir mekanizma gibi görünse de, aslında çok daha derin bir amaca hizmet eder ve React’in deklaratif doğası ile imperatif dünya arasındaki kritik bir köprüdür. Bu makale, useRef‘in sadece ne işe yaradığını değil, neden var olduğunu, hangi sorunları çözdüğünü ve React ekosistemindeki gerçek yerini anlamanıza yardımcı olmayı amaçlamaktadır.
useRef Nedir? Yüzeydeki Anlamı
useRef hook’u, React fonksiyonel bileşenlerinde mutable (değiştirilebilir) bir değer tutmak için kullanılan bir araçtır. Fonksiyonel bileşenler her render edildiğinde baştan sona çalışır ve yerel değişkenler her seferinde yeniden başlatılır. useRef ise, bileşenin yaşam döngüsü boyunca değerini koruyan ve her render’da sıfırlanmayan bir referans objesi sağlar.
DOM Referanslarına Erişim
useRef‘in en yaygın ve bilinen kullanım alanı, doğrudan bir DOM elementine referans almak ve ona imperatif olarak erişmektir. Örneğin, bir input alanına odaklanmak, bir medya oynatıcıyı kontrol etmek veya bir animasyonu başlatmak gibi durumlarda useRef kullanılır. React, genellikle DOM’u doğrudan manipüle etmekten kaçınsa da, bazı durumlarda bu tür doğrudan erişim kaçınılmaz hale gelir.
ref Niteliği ile Bağlantı
Bir useRef objesini bir DOM elementine bağlamak için, JSX içindeki elemente ref niteliği atanır. Bu, React’in ilgili DOM düğümünü useRef objesinin current özelliğine atamasını sağlar.
useRef hook'u, current adında tek bir özelliğe sahip basit bir JavaScript objesi döndürür. Bu current özelliği, referans alınan değeri veya DOM elementini tutar. useRef(initialValue) çağrıldığında, initialValue değeri current özelliğine atanır. Bu değer, bileşen yeniden render edildiğinde bile korunur.
useRef Neden Var? Temel İhtiyaç ve Felsefesi
useRef'in varoluş nedeni, React'in deklaratif doğası ile bazı imperatif gereksinimler arasındaki boşluğu doldurmaktır. React, genellikle UI'nın nasıl görüneceğini state'e göre tanımlamanızı isterken, bazen doğrudan bir şey "yapmanız" gerekir.
React'in Deklaratif Yapısı
React, UI'yı state'in bir fonksiyonu olarak tanımladığınız deklaratif bir kütüphanedir. Siz state'i değiştirirsiniz, React ise bu değişikliğe göre DOM'u günceller. Bu yaklaşım, karmaşık UI'ları yönetmeyi çok daha kolay hale getirir çünkü doğrudan DOM manipülasyonuyla uğraşmak zorunda kalmazsınız.
İmperatif İşlemler İçin Bir Köprü
Ancak bazı durumlarda, deklaratif yaklaşım yeterli olmaz. Örneğin, bir input alanına odaklanmak, bir video oynatıcıyı durdurmak veya bir canvas üzerinde çizim yapmak gibi işlemler doğrudan DOM API'leri aracılığıyla yapılır ve bunlar imperatif işlemlerdir. useRef, React'in deklaratif dünyasından çıkıp bu tür imperatif işlemleri güvenli bir şekilde gerçekleştirmemizi sağlayan bir köprü görevi görür.
Component Yaşam Döngüsü Boyunca Değerleri Korumak
useRef'in daha az bilinen ancak kritik bir kullanım alanı, bileşenin yeniden render edilmesi durumunda bile belirli bir değeri korumaktır. useState'in aksine, useRef'in current özelliğini değiştirmek bileşenin yeniden render edilmesini tetiklemez. Bu özellik, özellikle performans açısından kritik durumlarda veya UI'yı etkilemeyen arka plan değerlerini saklamak için çok değerlidir.
useRef Kullanım Alanları: Ref'lere Erişmek
DOM referanslarına erişim, useRef'in en temel ve anlaşılır kullanım senaryosudur.
Odaklanma (Focus) Yönetimi
Bir formda belirli bir input alanına otomatik odaklanma veya bir düğmeye tıklandığında başka bir alana odaklanma gibi senaryolarda useRef kullanılır.
import React, { useRef, useEffect } from 'react';
function FocusInput() {
const inputRef = useRef(null);
useEffect(() => {
// Bileşen yüklendiğinde input'a otomatik odaklan
inputRef.current.focus();
}, []); // Sadece bir kez çalışır
return (
);
}
Medya Oynatıcı Kontrolü
Bir veya elementi üzerinde oynatma, duraklatma, ses seviyesini ayarlama gibi kontrolleri uygulamak için de useRef'ten faydalanılır.
Tarayıcınız video etiketini desteklemiyor.
movie.mp4
);
}
Üçüncü Parti Kütüphanelerle Entegrasyon
Bazı üçüncü parti kütüphaneler (örneğin, grafik kütüphaneleri, harita bileşenleri) DOM elementlerine doğrudan erişim gerektirebilir. useRef bu kütüphanelerin React bileşenleriyle entegrasyonunu kolaylaştırır.
useRef Kullanım Alanları: Değişken Değerleri Saklamak (Mutasyon)
useRef'in DOM dışındaki en güçlü kullanım alanlarından biri, bileşenin yaşam döngüsü boyunca mutable değerleri saklamaktır.
Yeniden Render Tetiklemeyen Değişkenler
useState'in aksine, useRef'in current özelliğini değiştirmek bileşenin yeniden render edilmesini tetiklemez. Bu, UI'yı etkilemeyen ancak bileşen içinde kalıcı olması gereken değerler için idealdir. Örneğin, bir sayaç değeri, bir zamanlayıcı kimliği veya bir önceki prop değeri gibi.
Önceki Değerleri Saklama
Bir değerin önceki halini tutmak, useEffect hook'u ile birlikte useRef kullanılarak sıkça karşılaşılan bir senaryodur.
import React, { useRef, useEffect } from 'react';
function PreviousValueDisplay({ count }) {
const prevCountRef = useRef();
useEffect(() => {
prevCountRef.current = count; // Mevcut sayıyı bir sonraki render için sakla
}, [count]); // count her değiştiğinde çalışır
const previousCount = prevCountRef.current;
return (
Mevcut Sayı: {count}
Önceki Sayı: {previousCount}
);
}
Zamanlayıcı Kimlikleri (Timer IDs)
setInterval veya setTimeout gibi zamanlayıcı fonksiyonları kullanıldığında, bu zamanlayıcıları temizlemek için döndürdükleri ID'leri saklamak gerekir. useRef, bu ID'leri bileşenin yaşam döngüsü boyunca güvenli bir şekilde tutmak için mükemmel bir yerdir.
useRef ve Performans: Yeniden Render Etmeden Değerleri Korumak
useRef'in performansa katkısı, özellikle büyük ve karmaşık uygulamalarda göz ardı edilemez.
Gereksiz Render'ları Engelleme
Bir değer değiştiğinde bileşenin yeniden render edilmesini istemediğimiz durumlarda useRef kullanmak, useState'e göre önemli bir performans avantajı sağlar. useState ile bir değeri güncellediğinizde, React bileşeni yeniden render eder. Ancak useRef.current değerini değiştirmek, bu yeniden render işlemini tetiklemez. Bu, özellikle sık güncellenen ancak UI'yı doğrudan etkilemeyen değerler için kritik öneme sahiptir.
Hafıza Yönetimi
useRef ile oluşturulan referans objesi, bileşen hafızadan kaldırıldığında (unmount olduğunda) otomatik olarak temizlenir. Bu, hafıza sızıntılarını önlemeye yardımcı olur. Ancak current özelliğine atadığınız değerin kendisi için ek temizlik gerekebilir (örneğin, bir event listener veya bir zamanlayıcı).
Büyük Veri Setleri ve Referanslar
Bazen bir bileşen içinde büyük bir veri yapısını veya karmaşık bir objeyi tutmanız gerekebilir, ancak bu objenin her değiştiğinde bileşenin yeniden render edilmesini istemezsiniz. useRef bu tür durumlarda, objeye bir referans tutarak ve gerektiğinde doğrudan bu referans üzerinden manipülasyon yaparak performans avantajı sağlayabilir.
useRef vs. useState: Ne Zaman Hangisini Kullanmalı?
Bu iki hook arasındaki farkı anlamak, React uygulamalarında doğru aracı seçmek için hayati öneme sahiptir.
useState: UI'yı Etkileyen Durumlar
useState, bir bileşenin UI'sını etkileyen ve her değiştiğinde bileşenin yeniden render edilmesini gerektiren durumları (state) yönetmek için kullanılır. Kullanıcı etkileşimleri, veri çekme sonuçları gibi doğrudan kullanıcı arayüzünde görünür bir değişikliğe yol açan her şey useState ile yönetilmelidir.
useRef: UI'yı Doğrudan Etkilemeyen Değerler
useRef ise, aşağıdaki durumlar için tercih edilmelidir:
* DOM elementlerine doğrudan erişim gerektiğinde.
* Bileşenin yaşam döngüsü boyunca kalıcı olması gereken, ancak UI'yı etkilemeyen mutable değerleri saklamak için (örneğin, zamanlayıcı ID'leri, önceki değerler, performans sayaçları).
* Yeniden render'ı tetiklemeden bir değeri güncellemek gerektiğinde.
Ortak Kullanım Senaryoları Karşılaştırması
Aşağıdaki tablo, useState ve useRef arasındaki temel farkları özetlemektedir:
| Özellik | useState | useRef |
| :---------------- | :------------------------------------------- | :--------------------------------------------- |
| Amaç | UI durumunu yönetmek, yeniden render tetiklemek | Mutable değerleri veya DOM referanslarını tutmak |
| Render Etkisi | Değişimde bileşeni yeniden render eder | Değişimde bileşeni yeniden render etmez |
| Değer Tipi | Immutable (genellikle) | Mutable |
| Başlangıç Değeri | Her render'da yeniden başlatılır | Yalnızca ilk render'da başlatılır, sonra korunur |
| Kullanım Alanı | Form girişleri, toggle durumları, veri listeleri | DOM erişimi, zamanlayıcı ID'leri, önceki değerler |
useRef ile İlgili Dikkat Edilmesi Gerekenler ve Yaygın Hatalar
useRef güçlü bir araç olsa da, yanlış kullanıldığında beklenmedik davranışlara veya hatalara yol açabilir.
current Özelliğinin Mutasyonu
useRef tarafından döndürülen objenin current özelliğini doğrudan değiştirmek güvenlidir ve amaçlanan bir kullanımdır. Ancak, useRef'in kendisini (yani ref objesini) doğrudan değiştirmeye çalışmaktan kaçının.
Render Sırasında ref.current Değerini Okuma/Yazma
React'in render fazı saf olmalıdır, yani yan etkiler içermemelidir. ref.current değerini okumak veya yazmak, özellikle bu değer UI'nın render edilme şeklini etkiliyorsa, yan etki olarak kabul edilebilir. Bu tür işlemler genellikle useEffect hook'u içinde yapılmalıdır.
// KÖTÜ KULLANIM: Render sırasında yan etki
function BadComponent() {
const myRef = useRef(0);
myRef.current = myRef.current + 1; // Her render'da ref'i değiştiriyor
// Bu beklenmedik davranışlara yol açabilir
return
Sayı: {myRef.current}
;
}
// İYİ KULLANIM: useEffect içinde yan etki
function GoodComponent() {
const myRef = useRef(0);
useEffect(() => {
myRef.current = myRef.current + 1; // Yan etki useEffect içinde
}, []); // Sadece ilk render'da çalışır
return
Sayı: {myRef.current}
;
}
ref'leri Props Olarak Geçirme
Bir useRef objesini doğrudan bir alt bileşene ref prop'u olarak geçirmek, React'in ref yönetim sistemiyle çakışabilir. Eğer bir alt bileşenin DOM'una erişmek istiyorsanız, forwardRef API'sini kullanmanız gerekir.
useRef hook'u, React'in deklaratif paradigması içinde imperatif operasyonlar gerçekleştirmek ve bileşen yaşam döngüsü boyunca mutable değerleri korumak için vazgeçilmez bir araçtır. Sadece DOM elementlerine erişimden çok daha fazlasını sunar; gereksiz yeniden render'ları önleyerek performansı artırır ve karmaşık state yönetimi senaryolarında useState'e güçlü bir alternatif sunar. useRef'in ne zaman ve neden kullanıldığını gerçekten anlamak, daha sağlam, verimli ve bakımı kolay React uygulamaları geliştirmenizi sağlayacaktır. Artık useRef'in sadece ne yaptığını değil, neden var olduğunu ve React ekosistemindeki stratejik önemini de biliyorsunuz.
SSS (Sık Sorulan Sorular)
useRef ile useState arasındaki temel fark nedir?
useState, UI'yı etkileyen ve değiştiğinde bileşenin yeniden render edilmesini tetikleyen durumları yönetmek için kullanılır. useRef ise, bileşenin yaşam döngüsü boyunca kalıcı olması gereken, ancak değiştiğinde yeniden render'ı tetiklemeyen mutable değerleri veya DOM referanslarını tutmak için kullanılır.
useRef ne zaman null olur?
useRef(null) ile başlatıldığında current özelliği başlangıçta null olur. Eğer bir DOM elementine bağlanmışsa, bileşen mount edildiğinde current özelliği ilgili DOM elementine işaret eder. Bileşen unmount edildiğinde ise current tekrar null olabilir (React tarafından otomatik olarak).
useRef ile oluşturulan değerler component'in her render'ında sıfırlanır mı?
Hayır, useRef ile oluşturulan değerler, current özelliği aracılığıyla bileşenin tüm yaşam döngüsü boyunca korunur ve her render'da sıfırlanmaz. Yalnızca bileşen ilk kez mount edildiğinde initialValue ile başlatılır.
useRef'i forwardRef ile nasıl kullanırım?
Bir üst bileşenden alt bileşenin DOM elementine veya bir React bileşenine ref geçirmek için forwardRef kullanılır. forwardRef, bir bileşenin ref'i bir alt bileşene "iletmesine" olanak tanır. Alt bileşen bu ref'i kendi içinde bir DOM elementine veya başka bir React bileşenine atayabilir.
Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.