Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Effects, Refs and Reuse  ›  Lesson

useRef — Remembering Without Re-rendering

useRef 14 minuseRef returns a box whose current value persists across renders without triggering a re-render, used for DOM elements and for values the screen does not show.

useRef — Remembering Without Re-rendering

When you click Add book, the cursor should jump straight into the title field. React describes the page with JSX, but focusing an input means talking to the actual DOM element. You need a way to hold on to it. That is one of two jobs for a ref.

The rule

A ref is a box that remembers but never re-renders.

import { useRef } from 'react';

function AddBookForm() {
  const titleRef = useRef(null);

  function handleAddClick() {
    titleRef.current.focus();
  }

  return (
    <>
      <input ref={titleRef} placeholder="Title" />
      <button onClick={handleAddClick}>Add book</button>
    </>
  );
}

useRef(initial) returns an object with one property, current. React gives you the same object on every render, so whatever you put in current stays there.

Job one — DOM access. Pass the ref to an element with ref={titleRef}. After React commits, titleRef.current is the real <input> node, so you can call focus(), scrollIntoView(), or measure its size. Before it is attached, current is null.

Job two — hidden memory. Any value the component must remember but does not show — an interval id, the previous value of a prop, a flag — can live in ref.current:

const intervalRef = useRef(null);

function start() {
  intervalRef.current = setInterval(tick, 1000);
}
function stop() {
  clearInterval(intervalRef.current);
}

Never re-renders. Changing ref.current does not tell React anything. That is its point — and its trap. If you store a displayed number in a ref, the screen will not update.

Two usage rules: read and write ref.current in event handlers and effects, not during rendering, because a ref is outside the pure render. And to pass a ref to your own component, React 19 lets you accept ref as a normal prop; older code wraps the component in forwardRef.

The shortcut

For every value a component remembers, ask: "Does the screen show it?" Yes → state. No → ref.

Sorting three valuesStep 1 of 3
  1. The number of likes

    It appears on the button. State.

Drills

Answer fast — trust the rule.

quick drill

What happens when you set countRef.current = 5?

quick drill

What is inputRef.current after <input ref={inputRef} /> has been committed?

quick drill

A counter shown on screen is stored in a ref and incremented on click. What do you see?

quick drill

Where should you call titleRef.current.focus()?

Remember

  • A ref is a box that remembers but never re-renders.
  • Does the screen show it? Yes → state; no → ref.
  • Trap: storing displayed values in refs, and touching refs during render.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainState or ref?

The add-book form should focus its title input when an 'Add book' button is clicked, and the component also needs to remember an interval id so it can stop a timer. Explain how useRef handles both, and why neither value belongs in state.