Accessing DOM Elements with useRef
Accessing DOM Elements with useRef
Section titled “Accessing DOM Elements with useRef”Introduction
Section titled “Introduction”The most common use of useRef is to get a direct reference to a DOM element. By passing the ref to a JSX element’s ref attribute, React sets ref.current to the DOM node after rendering. This lets you call imperative DOM methods like .focus(), .play(), or .getBoundingClientRect().
Basic Pattern
Section titled “Basic Pattern”import { useRef, useEffect } from 'react';
export default function AutoFocusInput() { const inputRef = useRef(null);
useEffect(() => { // inputRef.current is the <input> DOM node inputRef.current.focus(); }, []);
return <input ref={inputRef} type="text" placeholder="Auto-focused..." />;}Explanation: useRef(null) creates the ref object. ref={inputRef} tells React to set inputRef.current to the DOM node. After mount, useEffect calls .focus() on it.
Common DOM Access Patterns
Section titled “Common DOM Access Patterns”Measuring Element Size
Section titled “Measuring Element Size”function ElementMeasurer() { const elementRef = useRef(null); const [rect, setRect] = useState(null);
useEffect(() => { const el = elementRef.current; if (el) { setRect(el.getBoundingClientRect()); } }, []);
return ( <div> <div ref={elementRef} style={{ padding: '20px', border: '1px solid #ccc' }}> Measure me! </div> {rect && ( <p>Width: {rect.width}px, Height: {rect.height}px</p> )} </div> );}Media Playback Control
Section titled “Media Playback Control”function VideoPlayer({ src }) { const videoRef = useRef(null);
const play = () => videoRef.current?.play(); const pause = () => videoRef.current?.pause(); const skip = (seconds) => { if (videoRef.current) { videoRef.current.currentTime += seconds; } };
return ( <div> <video ref={videoRef} src={src} style={{ width: '100%' }} /> <button onClick={play}>▶ Play</button> <button onClick={pause}>⏸ Pause</button> <button onClick={() => skip(-10)}>⏪ -10s</button> <button onClick={() => skip(10)}>⏩ +10s</button> </div> );}Canvas Drawing
Section titled “Canvas Drawing”function DrawingCanvas() { const canvasRef = useRef(null);
useEffect(() => { const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); ctx.fillStyle = '#4f46e5'; ctx.fillRect(10, 10, 100, 100); }, []);
return <canvas ref={canvasRef} width={200} height={200} style={{ border: '1px solid #ccc' }} />;}Integrating with Third-Party Libraries
Section titled “Integrating with Third-Party Libraries”Many DOM-based libraries (charts, maps, animations) need a DOM node to attach to:
import { useRef, useEffect } from 'react';import Chart from 'chart.js';
function PriceChart({ data }) { const chartRef = useRef(null); const instanceRef = useRef(null);
useEffect(() => { // Create chart instance on mount instanceRef.current = new Chart(chartRef.current, { type: 'line', data: data });
// Destroy on unmount return () => instanceRef.current.destroy(); }, []);
useEffect(() => { // Update chart when data changes if (instanceRef.current) { instanceRef.current.data = data; instanceRef.current.update(); } }, [data]);
return <canvas ref={chartRef} />;}When to Use Ref vs. State for DOM
Section titled “When to Use Ref vs. State for DOM”| Use Case | Ref | State |
|---|---|---|
| Accessing DOM node | ✅ | ❌ |
| Measuring dimensions | ✅ | ❌ |
| Managing playback | ✅ | ❌ |
| Storing interval ID | ✅ | ❌ |
| Values that affect UI | ❌ | ✅ |
Summary
Section titled “Summary”- Use
useRef+refattribute to access DOM elements imperatively. - Read
ref.currentinside effects or event handlers (not during render). - Common uses: focus, measurements, media control, Canvas API, third-party libs.
- Refs don’t trigger re-renders — use
useStatewhen the UI needs to reflect the value.