DOM Refs (Preview)

`useRef` Holds a Pointer to a DOM Node

DOM Refs (Preview)

When you need the real DOM node — to focus an input, measure size, scroll into view — pass a ref to the element.

3 min read Level 2/5 #react#refs#useRef
What you'll learn
  • Get a DOM node out of React
  • Focus an input on mount
  • Know when refs are the right escape hatch

React tries to keep you out of the DOM, but sometimes you need it: auto-focus an input, measure an element’s size, scroll something into view. The escape hatch is useRef + the ref prop.

(This is a preview — the next chapter covers useRef in full.)

The Pattern

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

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return <input ref={inputRef} />;
}

Three pieces:

  1. useRef(null) — creates a ref object { current: null }
  2. ref={inputRef} on the element — React fills in inputRef.current with the DOM node
  3. Access inputRef.current in an effect

Why an Effect?

The ref is null during render — the DOM node doesn’t exist yet. React only sets inputRef.current AFTER the component mounts. The effect runs after mount, so the node is in place by then.

Measuring

function Measured() {
  const boxRef = useRef(null);
  const [width, setWidth] = useState(0);

  useEffect(() => {
    setWidth(boxRef.current.getBoundingClientRect().width);
  }, []);

  return <div ref={boxRef}>Width: {width}px</div>;
}

For something that re-measures on resize, pair this with a ResizeObserver (see Subscriptions).

Don’t Read From the DOM What You Can Read From State

If you’re using refs to read out an input’s value, you almost always want a controlled input instead — the value is in state already.

// ✗ Reading from the DOM
function handleSubmit() {
  console.log(inputRef.current.value);
}

// ✓ Reading from state
function handleSubmit() {
  console.log(name);
}

Refs are an escape hatch — useful, but not the default.

What’s In The Next Chapter

You’ll see refs in more depth — including using them to hold values that should survive renders without triggering re-renders (timers, previous values, third-party instances).

Chapter Done

That wraps effects and lifecycle. Next is The Hooks Library — the remaining built-in hooks and how to write your own.

Rules of Hooks →