useRef
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 nesnesinincurrent
ö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ğinizinitialValue
değerine ayarlanır. Daha sonra başka bir şeye ayarlayabilirsiniz. Eğer ref nesnesini bir JSX elemanınaref
özelliği olarak verirseniz, Reactcurrent
ö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.
Ö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.current
e yazmanın render’ı tetiklememesi nedeniyledir. Render için kullanılan bilgilerin state olması gerekir.
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.
Ö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
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:
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.