useRef
โš›๏ธ React 18+ ๐ŸŸข Chapter 20 of 39 ๐Ÿ“‚ Phase 08: Lifecycle and Effects ๐Ÿ“… 2026 Edition
๐Ÿ“Œ Covered in this chapter: Ref Definition ยท Accessing DOM Elements ยท Focusing an Input ยท Storing Timer IDs ยท Previous Value ยท Ref vs State
useRef gives you a way to hold onto a value or a real DOM element across renders, without triggering a re-render when it changes โ€” a fundamentally different tool from useState.
1Accessing a Real DOM Element
๐Ÿ’ป Example 1: Focusing an Input Programmatically
import { useRef } from "react";

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

  function focusInput() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={focusInput}>Focus</button>
    </>
  );
}
๐Ÿ” How This Works:

The ref attribute connects inputRef.current directly to the real DOM <input> element, giving access to native browser methods like .focus() that React itself doesn't expose through props.

2Refs vs State: The Key Difference
const [count, setCount] = useState(0);  // updating this RE-RENDERS the component
const renderCount = useRef(0);          // updating this does NOT re-render

renderCount.current = renderCount.current + 1;  // changes silently, no re-render triggered

Both hold a value across renders, but useState updates trigger a re-render while useRef updates don't. Use state for anything that should visibly update the UI; use a ref for values you need to track internally without affecting what's rendered โ€” like a timer ID or a previous value for comparison.

3Storing a Timer ID with useRef
function Stopwatch() {
  const [seconds, setSeconds] = useState(0);
  const timerRef = useRef(null);

  function start() {
    timerRef.current = setInterval(() => setSeconds((s) => s + 1), 1000);
  }

  function stop() {
    clearInterval(timerRef.current);
  }

  return (
    <>
      <p>{seconds}s</p>
      <button onClick={start}>Start</button>
      <button onClick={stop}>Stop</button>
    </>
  );
}

Storing the timer's ID in a ref (rather than state) is exactly right here โ€” the ID itself never needs to be displayed on screen, it just needs to persist between the start and stop function calls.

โš ๏ธ Using a Ref for Data That Should Actually Be in State

If you store something in a ref that actually needs to be shown on screen, the UI simply won't update when it changes โ€” since ref updates don't trigger a re-render. If a value needs to visibly affect what's rendered, it belongs in useState, not useRef.

๐Ÿ’ป Hands-on Interactive Practice Challenge

Build a component with an input and a button that, when clicked, selects (highlights) all the text currently in the input using a ref and the native .select() method.

React Practice Challenge โ–ถ Run in Compiler
import { useRef } from "react";

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

  return (
    <>
      <input ref={inputRef} defaultValue="Select me!" />
      <button onClick={() => inputRef.current.select()}>Select All Text</button>
    </>
  );
}
Run This Challenge in Online JS IDE โ†’
โ“ Frequently Asked Questions (FAQ)

Q Does changing a ref's .current value cause a re-render?

No โ€” this is the defining difference from useState. Changing ref.current is completely invisible to React's rendering system, which is exactly why refs are unsuitable for any value that needs to appear in the UI.

Q Can I use a ref instead of state just to avoid extra re-renders?

Only for values that genuinely never need to be displayed. If you store UI-relevant data in a ref to 'optimize' re-renders, the screen will simply fail to update correctly when that data changes โ€” a common and confusing beginner mistake.

OC
Written by Our Compiler Technical Editorial Team
Reviewed for accuracy & tested on React 18+ ยท Last updated August 2026