Halo, Sobat Koding! đź‘‹
Kita udah bahas useState (si berisik yang suka update UI) dan useEffect (si responsif). Sekarang, mari kita bahas ninja pendiam di dunia React hooks: useRef.
Kalau useState itu ibarat pembawa berita yang teriak “BERITA TERKINI!” tiap ada yang berubah, useRef itu kayak mata-mata yang nyatet di pojokan. Dia tau ada yang berubah, tapi dia gak bikin heboh.
Yuk kita bedah kenapa kamu butuh “Si Pengamat Diam” ini. 🕵️‍♂️
Apa sih useRef itu sebenernya?
Simpelnya, useRef itu bikin objek JavaScript biasa yang nyimpen sebuah nilai.
Bentuknya kayak gini:
{ current: ... }
Udah, gitu doang. Cuma kotak dengan properti current.
Tapi ini kekuatan supernya: Mengubah ref.current TIDAK memicu re-render.
Ini bikin dia sempurna buat dua hal:
- Mengakses elemen DOM secara langsung.
- Nyimpen nilai yang bertahan antar render tapi gak perlu ditampilin di layar.
1. Mengakses DOM (Cara Paling Umum)
Kadang Virtual DOM-nya React aja gak cukup. Kamu butuh megang elemen HTML aslinya buat nge-fokusin input, scroll ke div tertentu, atau ngukur ukuran elemen.
Ini contoh klasik “Fokus Input”:
import { useRef, useEffect } from "react";
const SearchBar = () => {
const inputRef = useRef(null); // 1. Bikin ref-nya
const handleFocus = () => {
// 3. Akses node DOM pake .current
inputRef.current.focus();
};
return (
<div>
{/* 2. Tempel ref ke elemen */}
<input ref={inputRef} type="text" placeholder="Cari..." />
<button onClick={handleFocus}>Fokus ke Input</button>
</div>
);
};
Apa yang terjadi?
Pas React bikin <input>, dia masukin node DOM aslinya ke dalem inputRef.current. Sekarang kamu bisa panggil method DOM biasa kayak .focus(), .scrollIntoView(), dll.
2. Nyimpen Variabel Mutable (“Memori Rahasia”)
Ini kasus yang sering bikin orang bingung. Bayangin kamu mau ngitung berapa kali tombol diklik, tapi kamu gak mau nge-render ulang komponen cuma buat nyimpen angka itu (mungkin buat dikirim ke analytics nanti).
Kalau pake useState, komponen bakal re-render tiap klik.
Kalau pake variabel biasa (let count = 0), nilainya bakal balik jadi 0 tiap re-render.
Solusinya: useRef.
import { useRef, useState } from "react";
const ClickTracker = () => {
const [dummyState, setDummyState] = useState(0);
const clickCount = useRef(0); // Mulai dari 0
const handleClick = () => {
clickCount.current = clickCount.current + 1;
console.log(`Tombol diklik ${clickCount.current} kali`);
};
return (
<div>
<button onClick={handleClick}>Klik Aku (Cek Console)</button>
{/* Tombol ini cuma buat maksa re-render buat buktiin ref-nya awet */}
<button onClick={() => setDummyState(dummyState + 1)}>
Paksa Re-render
</button>
</div>
);
};
Coba simulasiin di kepala:
- Klik “Klik Aku” 5 kali. Console bilang “5”. Layar GAK BERUBAH.
- Klik “Paksa Re-render”. Komponen jalan ulang.
clickCount.currentMASIH 5. Dia gak kereset!
Aturan Emas ⚠️
JANGAN baca atau tulis ref.current pas lagi rendering.
React maunya rendering itu “murni” (pure). Baca/tulis ref pas render bikin hasilnya gak bisa ditebak.
// ❌ SALAH (JANGAN DITIRU)
const Component = () => {
const count = useRef(0);
count.current = count.current + 1; // Nulis pas render!
return <h1>{count.current}</h1>; // Baca pas render!
};
// âś… BENAR
const Component = () => {
const count = useRef(0);
useEffect(() => {
count.current = count.current + 1; // Nulis di Effect aman
});
return <h1>{count.current}</h1>; // (Masih agak riskan kalau sering berubah, mending State buat UI)
};
Kalau kamu mau nampilin sesuatu di layar, pake useState.
Kalau kamu mau nyimpen sesuatu “di belakang layar”, pake useRef.
Ringkasan
Bayangin komponen kamu itu orang kantoran.
useState: Itu bajunya. Kalau dia ganti baju, semua orang sadar (Re-render).useRef: Itu catetan kecil di sakunya. Dia bisa coret-coret, baca, dan simpen catetan itu, tapi gak ada orang lain yang liat perubahannya.
Gunakan useRef saat kamu butuh keluar dari aliran React (akses DOM) atau nyimpen rahasia dari UI (variabel mutable).
Selamat Ngoding! 🚀