Sometimes you need the real element
Focus a search box, scroll to a message, play a video, keep a timer id — these need either the actual DOM element or a value that shouldn't cause a re-render. That's a ref.
useRef
import { useRef, useState } from "react";
export default function Stopwatch() {
const [ms, setMs] = useState(0);
const timer = useRef(null);
const input = useRef(null);
function start() {
if (timer.current) return;
timer.current = setInterval(() => setMs((m) => m + 100), 100);
}
function stop() {
clearInterval(timer.current);
timer.current = null;
}
return (
<div>
<p>{(ms / 1000).toFixed(1)} s</p>
<button onClick={start}>Start</button>
<button onClick={stop}>Stop</button>
<input ref={input} placeholder="Your name" />
<button onClick={() => input.current.focus()}>Focus the name box</button>
</div>
);
}- Use state for what's shown on screen; refs for everything else you need to remember.
- Don't read or write ref.current during rendering — only in handlers and effects.