Refs
Refs
A Ref (short for Reference) is a special feature in React that allows you to directly access a DOM element or persist a mutable value across renders without causing the component to re-render.
In functional components, you create a ref using the useRef hook.
The Problem Refs Solve
React is fundamentally declarative. You define state, and React figures out how to update the DOM to match that state (UI = f(state)).
However, there are times when you need to step outside of this declarative model and interact with the DOM imperatively.
Common use cases for Refs include:
- Managing focus, text selection, or media playback (e.g., calling
input.focus()orvideo.play()). - Measuring the size or position of a DOM node.
- Integrating with third-party, non-React DOM libraries (like D3.js, GSAP, or a jQuery plugin).
How to Use a Ref for the DOM
- Create a ref using
useRef(null). - Pass the ref object as the
refattribute to a JSX element. - Access the DOM node via the
ref.currentproperty.
import { useRef } from 'react';
function TextInput() {
// 1. Create a ref
const inputRef = useRef(null);
const focusInput = () => {
// 3. Access the actual DOM node using .current
inputRef.current.focus();
};
return (
<div>
{/* 2. Attach the ref to the element */}
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focus</button>
</div>
);
}
The current Property
When you pass a ref object to a React element (<div ref={myRef} />), React will wait until the component has mounted (been added to the DOM), and then it will assign the actual DOM node to the myRef.current property.
When the component unmounts, React will automatically set myRef.current back to null.
Important: Because ref.current is not set until after the initial render, you should not try to access it directly inside the main body of your component. You should only access it inside event handlers or inside useEffect / useLayoutEffect.
function MyComponent() {
const divRef = useRef(null);
// ❌ BAD: divRef.current is null during the initial render!
// console.log(divRef.current.clientWidth);
useEffect(() => {
// ✅ GOOD: Inside useEffect, the component has mounted, so .current exists
console.log(divRef.current.clientWidth);
}, []);
return <div ref={divRef}>Hello</div>;
}
Interview Questions
Q: When should you explicitly avoid using refs?
A: You should never use a ref as a substitute for State. If you find yourself reading a ref’s value to decide what to render on the screen, or trying to display a ref’s value inside JSX, you are doing it wrong—that data belongs in useState.