useRef adalah sebuah React Hook yang memungkinkan Anda mereferensikan sebuah nilai yang tidak diperlukan untuk rendering.

const ref = useRef(initialValue)

Referensi

useRef(initialValue)

Panggil useRef di tingkat atas komponen Anda untuk mendeklarasikan sebuah ref.

import { useRef } from 'react';

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

Lihat lebih banyak contoh di bawah ini.

Parameters

  • initialValue: Nilai yang Anda inginkan untuk properti current objek ref pada awalnya. Nilai ini dapat berupa nilai dari jenis apa pun. Argumen ini akan diabaikan setelah render awal.

Returns

useRef mengembalikan sebuah objek dengan satu properti:

  • current: Awalnya, ini diatur ke initialValue yang telah Anda oper. Anda dapat mengaturnya ke nilai yang lain. Jika Anda mengoper objek ref ke React sebagai sebuah atribut ref ke node JSX, React akan menyetelkan properti current-nya.

Pada render berikutnya, useRef akan mengembalikan objek yang sama.

Perhatian

  • Anda dapat mengubah properti ref.current. Tidak seperti state, properti ini tidak dapat diubah. Namun, jika properti ini menyimpan objek yang digunakan untuk rendering (misalnya, sebuah bagian dari state Anda), maka Anda tidak boleh mengubah objek tersebut.
  • Ketika Anda mengubah properti ref.current, React tidak me-render ulang komponen Anda. React tidak mengetahui kapan Anda mengubahnya karena ref adalah objek JavaScript biasa.
  • Jangan menulis atau membaca ref.current selama proses rendering, kecuali untuk inisialisasi. Hal ini membuat perilaku komponen Anda tidak dapat diprediksi.
  • Dalam Strict Mode, React akan memanggil fungsi komponen Anda dua kali untuk membantu Anda menemukan bug yang tidak disengaja. Ini adalah perilaku khusus development dan tidak mempengaruhi produksi. Setiap objek ref akan dibuat dua kali, tetapi salah satu versi akan dibuang. Jika fungsi komponen Anda murni (sebagaimana mestinya), hal ini seharusnya tidak mempengaruhi perilaku.

Penggunaan

Mereferensikan sebuah nilai dengan sebuah ref

Panggil useRef di tingkat atas komponen Anda untuk mendeklarasikan satu atau lebih ref.

import { useRef } from 'react';

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

useRef mengembalikan sebuah objek ref dengan satu properti current pada awalnya diatur ke initialValue yang Anda sediakan.

Pada render berikutnya, useRef akan mengembalikan objek yang sama. Anda dapat mengubah properti current untuk menyimpan informasi dan membacanya nanti. Hal ini mungkin mengingatkan Anda pada state, tetapi ada sebuah perbedaan penting.

Mengubah sebuah ref tidak memicu render ulang. Ini berarti ref sangat cocok untuk menyimpan informasi yang tidak memengaruhi keluaran visual komponen Anda. Sebagai contoh, jika Anda perlu menyimpan sebuah ID interval dan mengambilnya nanti, Anda bisa menaruhnya di dalam ref. Untuk pembaruan nilai di dalam ref, Anda perlu mengubah secara manual nilai properti current:

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

Nantinya, Anda dapat membaca ID interval tersebut dari ref sehingga Anda dapat memanggil pembersihan interval tersebut:

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

Dengan menggunakan ref, Anda memastikan bahwa:

  • Anda dapat menyimpan informasi di antara render ulang (tidak seperti variabel biasa, yang disetel ulang pada setiap render).
  • Mengubahnya tidak memicu sebuah render ulang (tidak seperti variabel state, yang memicu sebuah render ulang).
  • Informasinya bersifat lokal untuk setiap salinan komponen Anda (tidak seperti variabel di luar, yang dibagikan).

Mengubah sebuah ref tidak akan memicu sebuah render ulang, jadi ref tidak sesuai untuk menyimpan informasi yang ingin Anda tampilkan di layar. Gunakan state untuk itu. Baca lebih lanjut tentang memilih antara useRef dan useState.

Contoh mereferensikan sebuah nilai dengan useRef

Example 1 of 2:
Klik penghitung

Komponen ini menggunakan sebuah ref untuk melacak berapa kali tombol diklik. Perhatikan bahwa tidak masalah untuk menggunakan sebuah ref dan bukan state di sini karena jumlah klik hanya dibaca dan ditulis di dalam event handler.

import { useRef } from 'react';

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

  function handleClick() {
    ref.current = ref.current + 1;
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>
      Click me!
    </button>
  );
}

Jika Anda menampilkan {ref.current} di dalam JSX, nomor tersebut tidak akan memperbarui saat mengeklik. Hal ini karena pengaturan ref.current tidak memicu sebuah render ulang. Informasi yang digunakan untuk rendering harus berupa state.

Pitfall

Jangan menulis atau membaca ref.current selama proses rendering.

React mengharapkan bahwa tubuh komponen Anda berperilaku seperti fungsi murni:

  • Jika masukan-masukan (props, state, dan context) yang sama, seharusnya mengembalikan JSX yang sama persis.
  • Memanggilnya dengan urutan yang berbeda atau dengan argumen yang berbeda tidak akan mempengaruhi hasil panggilan lainnya.

Membaca atau menulis ref selama rendering melanggar ekspektasi-ekspektasi ini.

function MyComponent() {
// ...
// 🚩 Don't write a ref during rendering
myRef.current = 123;
// ...
// 🚩 Don't read a ref during rendering
return <h1>{myOtherRef.current}</h1>;
}

Anda dapat membaca atau menulis ref dari event handler atau effect sebagai gantinya.

function MyComponent() {
// ...
useEffect(() => {
// βœ… You can read or write refs in effects
myRef.current = 123;
});
// ...
function handleClick() {
// βœ… You can read or write refs in event handlers
doSomething(myOtherRef.current);
}
// ...
}

Jika Anda harus membaca atau menulis sesuatu selama rendering, gunakan state sebagai gantinya.

Ketika Anda melanggar aturan-aturan ini, komponen Anda mungkin masih dapat berfungsi, tetapi sebagian besar fitur baru yang kami tambahkan ke React akan bergantung pada ekspektasi ini. Baca lebih lanjut tentang menjaga komponen Anda tetap murni.


Memanipulasi DOM dengan sebuah ref

Sangat umum menggunakan sebuah ref untuk memanipulasi DOM. React memiliki dukungan bawaan untuk hal ini.

Pertama, deklarasikan sebuah objek ref dengan sebuah initialValue dari null:

import { useRef } from 'react';

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

Kemudian oper objek ref Anda sebagai atribut ref ke JSX milik node DOM yang ingin Anda manipulasi:

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

Setelah React membuat node DOM dan meletakkannya di layar, React akan mengatur properti current objek Anda yang merujuk ke node DOM tersebut. Sekarang Anda dapat mengakses node DOM dari <input> dan memanggil method seperti focus():

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

React akan menyetel properti current kembali ke null ketika node dihapus dari layar.

Baca lebih lanjut tentang [memanipulasi DOM dengan ref].(/learn/manipulating-the-dom-with-refs)

Contoh memanipulasi DOM dengan useRef

Example 1 of 4:
Memfokuskan sebuah masukan teks

Dalam contoh ini, mengeklik tombol akan memfokuskan masukan:

import { useRef } from 'react';

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

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

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}


Menghindari pembuatan ulang konten ref

React menyimpan nilai ref awal sekali dan mengabaikannya pada render berikutnya.

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

Meskipun hasil dari new VideoPlayer() hanya digunakan untuk render awal, Anda masih memanggil fungsi ini pada setiap render. Hal ini dapat menjadi boros jika Anda membuat objek yang besar.

Untuk mengatasinya, Anda dapat menginisialisasi ref seperti ini sebagai gantinya:

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

Biasanya, menulis atau membaca ref.current selama render tidak diperbolehkan. Namun, dalam kasus ini tidak masalah karena hasilnya akan selalu sama, dan kondisi ini hanya dijalankan selama inisialisasi sehingga dapat sepenuhnya diprediksi.

Deep Dive

Cara menghindari pemeriksaan null saat menginisialisasi useRef

Jika Anda menggunakan pemeriksa tipe dan tidak ingin selalu memeriksa null, Anda dapat mencoba pola seperti ini:

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

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

// ...

Di sini, playerRef itu sendiri dapat bernilai null. Namun, Anda harus dapat meyakinkan pemeriksa tipe Anda bahwa tidak ada kasus di mana getPlayer() mengembalikan null. Kemudian gunakan getPlayer() di dalam event handler Anda.


Pemecahan masalah

Saya tidak bisa mendapatkan ref ke komponen kustom

Jika Anda mencoba mengoper ref ke komponen Anda sendiri seperti ini:

const inputRef = useRef(null);

return <MyInput ref={inputRef} />;

Anda mungkin mendapatkan error di konsol:

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

Secara bawaan, komponen Anda sendiri tidak mengekspos ref ke node DOM di dalamnya.

Untuk memperbaikinya, cari komponen yang ingin Anda dapatkan ref-nya:

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

Dan kemudian membungkusnya dengan forwardRef seperti ini:

import { forwardRef } from 'react';

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

export default MyInput;

Kemudian komponen induk bisa mendapatkan ref ke sana.

Baca lebih lanjut tentang mengakses node DOM komponen lain.