React'ta Referanslar ve forwardRef Kullanımı

4 Aralık 2023

React'ta, UI değişikliklerini genellikle state ve props ile yönetiriz. Ancak, bazen DOM'a veya React elemanına doğrudan erişmemiz gerekebilir. İşte bu tür durumlarda referansları kullanırız.

İmperatif ve Deklaratif Yaklaşım

İmperatif programlama, adım adım yapılması gerekenleri belirtirken, deklaratif yaklaşımda geliştiriciler sadece sonucu tanımlar ve bu sonuca ulaşmak için gerekli adımlar kendi içinde yönetilir. React'ın deklaratif yaklaşımı, özellikle büyük ve karmaşık kullanıcı arayüzleri için büyük bir avantaj sağlar, çünkü uygulamaları daha öngörülebilir ve yönetilebilir hale getirir.

İmperatif ve deklaratif yaklaşımı daha iyi anlamak için ufak bir kod örneği yapalım:

// İMPERATİF YAKLAŞIM
 
// HTML
<button id="myButton">Tıkla Beni</button>
<div id="message"></div>
 
// JavaScript
document.getElementById('myButton').addEventListener('click', function() {
    var messageElement = document.getElementById('message');
    messageElement.innerText = 'Merhaba, düğmeye tıkladınız!';
});
// DEKLARATİF YAKLAŞIM
 
import React, { useState } from 'react';
 
function MyComponent() {
    // useState hook'u ile component'in durumunu (state) yönetiyoruz
    const [showMessage, setShowMessage] = useState(false);
 
    // Düğmeye tıklandığında çağrılacak fonksiyon
    const handleClick = () => {
        setShowMessage(true);
    };
 
    return (
        <div>
            <button onClick={handleClick}>Tıkla Beni</button>
            {showMessage && <div>Merhaba, düğmeye tıkladınız!</div>}
        </div>
    );
}
 
export default MyComponent;

Reference (Referans) Nedir?

React'ta bir "reference" (referans), DOM düğümlerine veya React elementlerine doğrudan erişim sağlamak için kullanılan bir mekanizmadır. React'ın deklaratif yaklaşımı nedeniyle, UI'daki değişiklikleri genellikle state ve props'larla yaparız. Ancak, bazen DOM'a doğrudan erişmek veya bir React component'inin örnek metodlarını çağırmak gerekebilir. İşte bu gibi durumlarda referanslar devreye girer.

import React, { useRef, useEffect } from 'react';
 
function MyInput() {
    // useRef Hook'u ile bir referans oluşturuyoruz
    const inputRef = useRef();
 
    useEffect(() => {
        // Component yüklendiğinde input alanına otomatik olarak odaklanıyoruz
        inputRef.current.focus();
    }, []); // Boş bağımlılık dizisi, useEffect'in sadece component yüklendiğinde çalışmasını sağlar
 
    return (
        <div>
            <input ref={inputRef} type="text" />
            <button onClick={() => inputRef.current.focus()}>
	            Focus to Input
            </button>
        </div>
    );
}
 
export default MyInput;

Burada useRef hook'u ile bir referans oluşturup input'un içerisinde ref={inputRef} şeklinde tanımlayarak bu referans'ı input'a bağlıyoruz. Ardından da inputRef.current ile ilgili elemente ulaşabiliyoruz. Burada .current kullanılmasının sebebi React'ın ref'i nasıl yönettiğiyle ilgilidir. Çünkü aslında elementi current içerisinde tutar ve her değişiklikte burayı günceller.

Peki ya forwardRef nedir?

forwardRef, oluşturulan referansları alt component'lere aktarmak için kullanılan bir mekanizmadır. Referanslar, doğrudan DOM elemanlarıyla ve class component'leriyle ilişkilendirilirken, functional component'lerde doğrudan bir ilişki kurulamaz. Bu sınırlandırmayı aşmak için forwardRef kullanılır.

import React, { forwardRef } from 'react';
 
const MyInput = forwardRef((props, ref) => (
  <input ref={ref} {...props} />
));
 
// Üst bileşende kullanımı
const MyComponent = () => {
  const inputRef = useRef();
 
  useEffect(() => {
    inputRef.current.focus(); // Input'a programatik olarak odaklanma
  }, []);
 
  return <MyInput ref={inputRef} type="text" />;
}

forwardRef iki parametre alır. Bunlar props ve ref'tir. Böylelikle kullanılan yerde hem prop'ların hem de ref'in kullanılmasını sağlar. Böylece ref'i de parent component'ten child component'e gönderebiliriz.

Sonuç

React'ta referans kullanımı, özellikle karmaşık etkileşimler ve DOM manipülasyonları için faydalı olabilir. Ancak, React ekibi, referans kullanımını mümkün olduğunca sınırlı tutmayı öneriyor. Aşırı veya yanlış kullanım, React'ın deklaratif yapısını bozabilir ve uygulamanın bakımını zorlaştırabilir.