UseRef ve ForwardRef

Oğuzhan Uyanık
Kodcular
Published in
4 min readAug 21, 2023

Bu yazıda, bir React Hook olan useRef ve bazı durumlarda birlikte kullanılan forwardRef’i inceleyeceğiz.

useRef

useRef, renderlar arası veri saklamak ve DOM manipülasyonu yapmak gibi iki farklı amaç için kullanılır.

1. useRef ile veri saklamak

React bileşenlerinde veri tutmak için stateler kullanılır. Ancak önceki render işleminde kullanılan bir veriye erişmek istediğimizde stateler yetersiz kalır. Bu gibi durumlarda useRef kullanarak verileri, renderlar arasında taşıyabiliriz. Aşağıdaki örneği inceledikten sonra altındaki açıklamasını okuyabilirsiniz.

  1. Bir inputumuz var ve aldığı değer inputValue isimli state içerisinde tutuluyor.
  2. Renderlar arasında veriyi koruyabilmek için bir useRef() nesnesi oluşturulmuş ve başlangıç değeri olarak boş string verilmiş.
  3. inputValue state’i her değiştiğinde tetiklenmesi için bir useEffect oluşturulmuş.
  4. useEffect içerisinde ise useRef değerine .current ile erişilerek değeri güncellenmiş.
  5. Sonuç olarak ekranda bir önceki renderdaki inputValue değeri ve şimdiki inputValue değeri yansıtılmış olur.

Yukarıdaki örnek ve açıklamalar useRef’in veri tutmak için kullanımına ilişkin en temel yapıyı göstermektedir. Ancak useRef ile ilgili aşağıdaki bilgiler de faydalı olacaktır.

  • useRef bir başlangıç değeri tutabilir. Eğer başlangıç değeri tanımlanmazsa başlangıçta undefined değerini alır.
  • useRef’e atanan değer bir obje içerisinde tutulur ve temsil ettiği bu değere erişmek için .current kullanılır.
  • useRef’de değişiklik yapıldığında React bu değişikliği fark etmez ve statelerde olduğu gibi componenti baştan render etmez.
  • React.StrictMode, geliştirme sürecinde bileşenleri iki defa render edebilir. Bu gibi durumlarda useRef ile saklanan veri sağlıklı saklanamayabilir. Sadece geliştirme sürecinde katı modu kaldırmak useRef ile çalışırken mantıklı olacaktır.
  • useRef ile saklanan verilerin ekranda görüntülenmeyen sadece mantıksal tarafta kullanılan veriler olması önerilir. Çünkü useRef değişikliği bileşenin yeniden render edilmesini sağlamaz, bu sebeple ekranda güncel veriler görülemeyebilir
  • useRef ile tutulan veri değiştirilirken, onClick gibi event listener veya useEffect gibi bir tetikleyici kullanılmalıdır. Doğrudan kod içerisine yazıldığında render işlemi sırasında değer değiştirilir ve beklenmeyen sonuçlar alınabilir.
  • useRef için büyük boyutlu bir nesne başlangıç değeri olarak atanmamalıdır. Bunun yerine aşağıdaki örnekteki gibi null olarak başlatılmalı ve koşula bağlı olarak ilgili veri tanımlanmalıdır.
  • useRef verileri senkronizedir. Güncellendiğinde anında erişilebilir. Ancak statelerin tuttuğu verilerin kullanılabilmesi için değişiklik sonrası bileşenin render edilmesi gerekir.
  • useRef ile setInterval’a ait referans değeri tutulabilir. Bu sayede sonraki renderlarda interval’i temizlemek mümkün olur.

2. useRef ile DOM manipülasyonu

DOM manipülasyonu HTML belgesindeki öğelere erişmek ve erişilen öğeyi değiştirmek veya tetiklemek gibi işlemler için kullanılır. React içerisinde çoğu zaman DOM manipülasyonu gerekmez ancak gerekli durumlarda useRef ile DOM’a erişilebilir. Hatırlatma olması açısından DOM manipülasyonuna JavaScript üzerinden bir örnek ile başlayalım.

Yukarıdaki örnekte bir öğeye erişilmiş ve daha sonra focus() ile öğeye odaklanılmıştır. Aynı örneği React ve useRef kullanarak yaptığımızda aşağıdaki gibi bir kod ortaya çıkar.

  • Bir useRef nesnesi oluşturulmuş (başlangıç değeri boş veya null olabilir).
  • input elementine, ref={ } özniteliği ile useRef nesnesi atanmış. Bu sayede useRef ile öğe ilişkilendirilmiş.
  • onClick ile tetiklenen bir fonksiyon içerisinde useRef nesnesine .current.focus() ile erişilerek DOM manipülasyonu gerçekleştirilmiş.
  • Bu örnekte onClick eventi ile DOM manipülasyonu tetiklenmiştir. Ancak component render edildiğinde gerçekleşmesi isteniyorsa useEffect ile aşağıdaki gibi yapılmalıdır.

Son olarak, DOM’a doğrudan erişim React’te genellikle kötü bir uygulama olarak görülür. Genel bir kural olarak, kaçınılmalı ve yalnızca çok özel koşullar altında ve kapsamlı bir inceleme ile kullanılmalıdır.

forwardRef

useRef ile veri saklarken bazı durumlarda alt bileşene bu ref değerini aktarmamız gerekebilir. Bu gibi durumlarda forwardRef ile birlikte kullanılmalıdır. Aksi halde, alt bileşen gönderilen ref değerini kullanamaz.

  • İki bileşenden oluşan yukarıdaki dosyada App bileşeni içerisinden MyInput bileşeni çağrılmaktadır.
  • DOM manipülasyonu için oluşturulan useRef nesnesi MyInput bileşenine öznitelik olarak gönderilmektedir.
  • Alt bileşen olan MyInput bileşeni forwardRef() ile sarılmıştır. Ve forwardRef ile sarılan tüm bileşenler props, ref olmak üzere iki değer alır. İlk parametre propları tutar, ikincisi ise gönderilen ref değerini.
  • Sonrasında alt bileşen, ref değerini input öğesi ile ilişkilendirir. Bu sayede üst bileşendeki butona tıklandığında alt bileşendeki input’a focus işlemi gerçekleşir.
  • forwardRef olmasaydı bu ref değeri alt bileşene iletilemeyecekti.

Tüm yazılarımın kategorize edilmiş bir listesine aşağıdaki linkten erişebilirsiniz.
https://github.com/oguzhanuyanik-sr/articles

--

--