In short
Sometimes you need to touch the real DOM, like focusing an input or scrolling a chat to the bottom. Or remember a value without re-rendering. That's what refs are for.
`useRef` gives you a mutable value that persists across renders without causing re-renders — commonly used to directly access a DOM element.

Think of it like this
Notes app vs WhatsApp status
Post a WhatsApp status and all your contacts see the update. Jot something in your notes app and nobody is notified, but it's still there when you need it. State is the status, because it re-renders. A ref is your notes app.
Watch it happen
Focus without a re-render
mount <input>
1/5React creates the real input element on the page.
The big ideas
What you need to know
useRef gives you a box
const box = useRef(initial) returns an object with a current property. Read or change current any time.
Changing it is silent
Updating ref.current doesn't re-render. Use it for timer IDs, previous values or anything the screen doesn't show.
Point at DOM elements
Pass ref={inputRef} to an element, and React fills inputRef.current with that DOM node after it mounts.
ref is a normal prop in React 19
Your own components can accept ref like any other prop. forwardRef is no longer needed.
See it in code
Walk through the code
1import { useRef } from "react";2 3export default function SearchBox() {4 const inputRef = useRef<HTMLInputElement>(null);5 6 return (7 <>8 <input ref={inputRef} placeholder="Search courses" />9 <button onClick={() => inputRef.current?.focus()}>Focus search</button>10 </>11 );12}1/3useRef creates a box whose current starts as null.
React puts the real input element into inputRef.current after it mounts. The ?. handles the moment before that, when current is still null.
Save yourself the pain
Common mistakes
Oops
Changing ref.current and expecting the screen to update.
Do this instead
Refs don't trigger renders. If a value should appear on screen, it belongs in state.
Oops
Using refs to set text or classes on elements by hand.
Do this instead
Let JSX handle what's shown. Use refs for things JSX can't do, like focus, scroll or measuring size.
Your mission
Stopwatch with refs
Quick check
You run countRef.current += 1 on every click and show {countRef.current} in JSX. What does the screen show?
Go deeper
- 1Use a ref to focus an input automatically when a component mounts.
- 2Store a previous value across renders using a ref, without triggering a re-render.
- 3Learn `forwardRef` for passing a ref through to a child component.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.