SyntaxStudy
Sign Up
React useRef for DOM Access and Persisting Values
React Beginner 1 min read

useRef for DOM Access and Persisting Values

useRef returns a plain JavaScript object with a single mutable property, current. Unlike state, mutating ref.current does not schedule a re-render, which makes refs the right tool when you need to store a value that must survive re-renders but whose changes should not cause the component to redraw — think timer IDs, previous prop values, or a reference to a third-party instance. The most common use-case is accessing a DOM node directly. Passing a ref as the ref prop of a JSX element stores the underlying DOM element in ref.current after the component mounts. From that point you can call DOM APIs such as focus, scrollIntoView, or getBoundingClientRect without leaving React. Be careful not to read or write refs during render. Because mutation is side-effectful, ref access belongs in event handlers, useEffect bodies, or imperative handle callbacks exposed via useImperativeHandle.
Example
import { useRef, useEffect, useState } from 'react';

function AutoFocusInput() {
    const inputRef = useRef(null);

    // Focus the input after mount
    useEffect(() => {
        inputRef.current?.focus();
    }, []);

    return <input ref={inputRef} placeholder="I get focus on mount" />;
}

function StopwatchWithRef() {
    const [elapsed, setElapsed] = useState(0);
    const intervalRef = useRef(null); // stores timer ID – NOT state

    function start() {
        if (intervalRef.current !== null) return; // already running
        const startTime = Date.now() - elapsed;
        intervalRef.current = setInterval(() => {
            setElapsed(Date.now() - startTime);
        }, 10);
    }

    function stop() {
        clearInterval(intervalRef.current);
        intervalRef.current = null;
    }

    return (
        <div>
            <p>{(elapsed / 1000).toFixed(2)}s</p>
            <button onClick={start}>Start</button>
            <button onClick={stop}>Stop</button>
        </div>
    );
}