iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

useRef

useRef returns a stable mutable object. The classic use is a DOM ref; it’s also the right tool for any value you want to read/write WITHOUT triggering a re-render — timers, previous values, instance counters.

DOM refs, timers, previous-value pattern

EXAMPLE
import { useRef, useEffect, useState } from 'react';

// 1) DOM reference
function Search() {
    const inputRef = useRef(null);
    useEffect(() => { inputRef.current?.focus(); }, []);
    return <input ref={inputRef} />;
}

// 2) Mutable value (no re-render)
function DoubleTap({ onDouble }) {
    const lastTap = useRef(0);
    function onPress() {
        const now = Date.now();
        if (now - lastTap.current < 300) onDouble();
        lastTap.current = now;
    }
    return <button onClick={onPress}>tap</button>;
}

// 3) Hold timer / interval IDs
function Timer() {
    const id = useRef(null);
    const [n, setN] = useState(0);
    useEffect(() => {
        id.current = setInterval(() => setN(c => c + 1), 1000);
        return () => clearInterval(id.current);
    }, []);
    return <p>{n}s</p>;
}

// 4) Previous-value pattern
function usePrevious(value) {
    const ref = useRef();
    useEffect(() => { ref.current = value; }, [value]);
    return ref.current;
}
function Diff({ value }) {
    const prev = usePrevious(value);
    return <p>now {value}, was {prev ?? '—'}</p>;
}

// 5) Imperative handle — expose methods up
import { forwardRef, useImperativeHandle } from 'react';
const Modal = forwardRef(function Modal(props, ref) {
    const dialogRef = useRef(null);
    useImperativeHandle(ref, () => ({
        open:  () => dialogRef.current.showModal(),
        close: () => dialogRef.current.close(),
    }));
    return <dialog ref={dialogRef}>…</dialog>;
});

Why it matters

useRef is for values that change but shouldn’t trigger renders. Anything you’d normally store as this.foo in a class component goes in a ref now.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
const inputRef = useRef(null);
useEffect(() => inputRef.current?.focus(), []);
return <input ref={inputRef} />;
Try it Yourself »

Discussion

Loading…