useRef render işlemi için gerekli olmayan bir değeri referans almanıza izin veren bir React Hook’tur.

const ref = useRef(initialValue)

Referans

useRef(initialValue)

Bir ref tanımlamak için useRef’i bileşeninizin en üst seviyesinde çağırın.

import { useRef } from 'react';

function MyComponent() {
const intervalRef = useRef(0);
const inputRef = useRef(null);
// ...

Daha fazla örnek için aşağıya bakın.

Parametreler

  • initialValue: Ref nesnesinin current özelliğinin başlangıçta olmasını istediğiniz değer. Herhangi türde bir değer olabilir. Bu argüman, ilk render işleminden sonra göz ardı edilir.

Geri Dönüş Değeri

useRef, tek bir özelliğe sahip bir nesne döndürür:

  • current: Başlangıçta, verdiğiniz initialValue değerine ayarlanır. Daha sonra başka bir şeye ayarlayabilirsiniz. Eğer ref nesnesini bir JSX elemanına ref özelliği olarak verirseniz, React current özelliğini tanımlayacaktır.

Sonraki render işlemlerinde, useRef aynı nesneyi döndürecektir.

Dikkat edilmesi gerekenler

  • ref.current özelliğini değiştirebilirsiniz. State’in aksine, bu değiştirilebilirdir. Ancak, render için kullanılan bir nesne tutuyorsa (örneğin, State’inizin bir parçası), o nesneyi değiştirmemelisiniz.
  • ref.current özelliğini değiştirdiğinizde, React bileşeninizi yeniden render etmez. Ref, düz JavaScript bir nesne olduğundan, ne zaman değiştirdiğinizi React fark etmez.
  • Bileşeninizin davranışını öngörülemez hale getireceğinden render işlemi sırasında, ref.current’e yazmayın veya okumayın. Ancak başlangıçta yapabilirsiniz.
  • Strict Mode’da, React istenmeyen yan etkileri bulmanıza yardımcı olmak için bileşeninizi iki kez çağıracaktır. Bu sadece geliştirme ortamı için geçerli bir davranıştır ve canlı ortamı etkilemez. Her bir ref nesnesi iki kez oluşturulacak, ancak bunlardan biri atılacaktır. Eğer bileşen fonksiyonunuz saf ise (olması gerektiği gibi), bu, davranışı etkilememelidir

Kullanım

Ref ile bir değeri referans gösterme

Bir veya daha fazla ref tanımlamak için bileşeninizin en üstünde useRef’i çağırın.

import { useRef } from 'react';

function Stopwatch() {
const intervalRef = useRef(0);
// ...

useRef başlangıçta verdiğiniz başlangıç değeri tanımlanmış bir şekilde sadece current özelliğine sahip bir ref nesnesi döndürür.

Sonraki render işlemlerinde, useRef aynı nesneyi döndürecektir. current özelliğini değiştirerek bilgi saklayabilir ve daha sonra okuyabilirsiniz. Bu size state özelliğini hatırlatabilir, ancak önemli bir fark var.

Bir ref’i değiştirmek yeniden render işlemine neden olmaz. Bu, ref’lerin bileşeninizin görsel çıktısını etkilemeyen bilgileri saklamak için mükemmel olduğu anlamına gelir. Örneğin, bir interval ID saklamak ve daha sonra geri almak istiyorsanız, bunu bir ref içine koyabilirsiniz. Ref içindeki değeri güncellemek için, current özelliğini manuel olarak değiştirmeniz gerekir:

function handleStartClick() {
const intervalId = setInterval(() => {
// ...
}, 1000);
intervalRef.current = intervalId;
}

Daha sonra, ref’ten o interval ID’yi okuyarak intervali durdurabilirsiniz:

function handleStopClick() {
const intervalId = intervalRef.current;
clearInterval(intervalId);
}

Bir ref kullanarak şunları sağlarsınız:

  • Yeniden render işlemleri arasında bilgi saklayabilirsiniz (her render işleminde sıfırlanan değişkenlerin aksine).
  • Değiştirmek yeniden render işlemine neden olmaz (yeniden render işlemine neden olan state değişkenlerinin aksine).
  • Bilgi, bileşeninizin her kopyasına özgüdür (paylaşılan dış değişkenlerin aksine).

Bir ref’i değiştirmek yeniden render işlemine neden olmaz, bu nedenle ekranda görüntülemek istediğiniz bilgileri saklamak için ref’ler uygun değildir. Bunun yerine state kullanın. useRef ve useState arasında nasıl seçim yapacağınıza dair daha fazla bilgi edinin.

useRef ile ref alma örnekleri

Örnek 1 / 2:
Tıklama sayacı

Bu bileşen, düğmenin kaç kez tıklandığını takip etmek için bir ref kullanır. Burada state yerine ref kullanmanın sorun olmadığına dikkat edin, çünkü tıklama sayısı yalnızca bir olay işleyicide okunur ve yazılır.

import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current = ref.current + 1;
    alert(ref.current + ' kere tıkladınız!');
  }

  return (
    <button onClick={handleClick}>
      Bana tıkla!
    </button>
  );
}

Eğer JSX’te {ref.current}’ü göstermek isterseniz, butona tıkladığınızda sayı güncellenmez. Bu, ref.currente yazmanın render’ı tetiklememesi nedeniyledir. Render için kullanılan bilgilerin state olması gerekir.

Tuzak

Render sırasında ref.current’i yazmayın veya okumayın.

React, bileşenin gövdesinin saf bir fonksiyon gibi davranmasını bekler:

  • Eğer inputlar (prop’lar, state ve context) aynıysa, tamamen aynı JSX’i döndürmelidir.
  • Farklı bir sırayla veya farklı argümanlarla çağrılması, diğer çağrıların sonuçlarını etkilememelidir.

Render sırasında bir ref’i okumak veya yazmak bu beklentileri bozar.

function MyComponent() {
// ...
// 🚩 Render sırasında bir ref'i yazmayın
myRef.current = 123;
// ...
// 🚩 Render sırasında bir ref'i okumayın
return <h1>{myOtherRef.current}</h1>;
}

Render sırasında değil, olay yöneticilerinden veya efektlerden ref’leri okuyabilir veya yazabilirsiniz.

function MyComponent() {
// ...
useEffect(() => {
// ✅ Ref'leri efektlerde okuyabilir veya yazabilirsiniz
myRef.current = 123;
});
// ...
function handleClick() {
// ✅ Ref'leri olay yöneticilerinde okuyabilir veya yazabilirsiniz
doSomething(myOtherRef.current);
}
// ...
}

Eğer render sırasında bir şey okumak veya yazmak zorunda kalırsanız, bunun yerine state kullanın.

Bu kuralları ihlal ettiğinizde, bileşeniniz hala çalışabilir, ancak React’e eklediğimiz yeni özelliklerin çoğu bu beklentilere bağlı olacaktır. Bileşenlerinizi saf tutma hakkında daha fazla bilgi edinin.


Bir ref ile DOM’u manipüle etmek

Bir ref’i DOM üzerinde değişiklik yapmak için kullanmak oldukça yaygındır. React’ın bunun için yerleşik desteği vardır.

İlk olarak, null başlangıç değeri olan bir ref nesnesi tanımlayın:

import { useRef } from 'react';

function MyComponent() {
const inputRef = useRef(null);
// ...

Ref nesnenizi, manipüle etmek istediğiniz DOM elemanının JSX’ine ref özelliği olarak verin:

// ...
return <input ref={inputRef} />;

React, DOM elemanını oluşturduktan ve ekrana koyduktan sonra, ref nesnenizin current özelliğini o DOM elemanına tanımlar. Şimdi <input>’un DOM elamanına erişebilir ve focus() gibi yöntemleri çağırabilirsiniz:

function handleClick() {
inputRef.current.focus();
}

Eleman ekrandan kaldırıldığında, React current özelliğini null olarak geri tanımlar.

Ref’lerle DOM’u manipüle etme hakkında daha fazla bilgi edinin.

useRef ile DOM'u manipüle etme örnekleri

Örnek 1 / 4:
Input’a odaklanma

Bu örnekte, düğmeye tıklamak input’a odaklanacaktır:

import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Input'a odaklan
      </button>
    </>
  );
}


Ref içeriğini yeniden oluşturmayı önleme

React, başlangıçtaki ref değerini bir kez kaydeder ve sonraki render işlemlerinde bunu dikkate almaz.

function Video() {
const playerRef = useRef(new VideoPlayer());
// ...

new VideoPlayer() sonucu sadece başlangıç render işleminde kullanılmasına rağmen, bu işlemi her render işleminde çağırıyorsunuz. Bu, eğer pahalı nesneler oluşturuyorsa israf olabilir.

Bunu çözmek için ref’i şu şekilde başlatabilirsiniz:

function Video() {
const playerRef = useRef(null);
if (playerRef.current === null) {
playerRef.current = new VideoPlayer();
}
// ...

Normalde, render sırasında ref.current yazmaya veya okumaya izin verilmez. Ancak bu senaryoda sorun yoktur çünkü sonuç her zaman aynıdır ve koşul sadece başlatma sırasında çalışır, bu nedenle tamamen öngörülebilirdir.

Derinlemesine İnceleme

useRef’i daha sonra başlatırken null kontrollerinden nasıl kaçınılır

Bir tip denetleyici kullanıyorsanız ve her zaman null kontrol etmek istemiyorsanız, bunun yerine şu şekilde bir model deneyebilirsiniz:

function Video() {
const playerRef = useRef(null);

function getPlayer() {
if (playerRef.current !== null) {
return playerRef.current;
}
const player = new VideoPlayer();
playerRef.current = player;
return player;
}

// ...

Burada playerRef kendisi boş olabilir. Ancak, getPlayer()’in null döndüren bir durum olmadığını tip denetleyicinize ikna etmelisiniz. Ardından, olay yöneticisinde getPlayer() kullanın.


Sorun Giderme

Özel bir bileşeni ref alamıyorum

Bileşeninize şu şekilde bir ref vermeyi denerseniz:

const inputRef = useRef(null);

return <MyInput ref={inputRef} />;

Konsolda bir hata alabilirsiniz:

Console
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Varsayılan olarak, kendi bileşenleriniz içlerindeki DOM elemanlarında ref’leri açığa çıkarmaz.

Bunu düzeltmek için, bir ref almak istediğiniz bileşeni bulun:

export default function MyInput({ value, onChange }) {
return (
<input
value={value}
onChange={onChange}
/>
);
}

Ve ardından bunu forwardRef ile şu şekilde sarın:

import { forwardRef } from 'react';

const MyInput = forwardRef(({ value, onChange }, ref) => {
return (
<input
value={value}
onChange={onChange}
ref={ref}
/>
);
});

export default MyInput;

Böylece ana bileşen ona bir ref alabilir.

Başka bir bileşenin DOM elemanına erişme hakkında daha fazla bilgi edinin.