Basic Usage
Call useRef at the top level of your component to declare a ref. You can then assign it to a DOM node or store any mutable value you want to persist across renders without causing them.
import { useRef } from 'react'
function TextInput() {
const inputRef = useRef(null)
function handleFocus() {
inputRef.current.focus()
}
return (
<div>
<input ref={inputRef} />
<button onClick={handleFocus}>Focus</button>
</div>
)
}useRef vs useState
Both store values between renders, but they behave very differently. Use this table to decide which hook fits your situation.
| Property | useRef | useState |
|---|---|---|
| Triggers re-render | No | Yes |
| Mutable directly | Yes | No (use setter) |
| Persists across renders | Yes | Yes |
| Best for | DOM refs, timers, prev values | UI-driven state |
Common Patterns
These are the most frequent real-world uses for useRef. Each avoids unnecessary re-renders by keeping the value outside of React’s state system.
-
DOM element access
Attach to a JSX element with the ref prop to read or manipulate it directly.
-
Storing timer IDs
Hold a setTimeout or setInterval ID to cancel it on cleanup without re-rendering.
-
Tracking previous values
Snapshot the previous render's value inside a useEffect for diffing.
-
Persisting across renders without state
Any value that needs to live between renders but shouldn't trigger UI updates.