useRef
Persist mutable values and access DOM nodes without causing re-renders
Overview
useRef returns a mutable object { current: value } that persists across renders. Updating .current does not trigger a re-render. Common uses: DOM references, storing previous values, and holding timer IDs.
Syntax / Usage
import { useRef, useEffect } from 'react'
function TextInput() {
const inputRef = useRef(null)
useEffect(() => {
inputRef.current?.focus()
}, [])
return <input ref={inputRef} />
}
function Timer() {
const intervalRef = useRef(null)
const start = () => {
intervalRef.current = setInterval(() => {
console.log('tick')
}, 1000)
}
const stop = () => clearInterval(intervalRef.current)
return (
<>
<button onClick={start}>Start</button>
<button onClick={stop}>Stop</button>
</>
)
}
Examples
Track previous prop value:
function usePrevious(value) {
const ref = useRef()
useEffect(() => {
ref.current = value
}, [value])
return ref.current
}
Measure element width:
function MeasuredBox({ children }) {
const ref = useRef(null)
const [width, setWidth] = useState(0)
useEffect(() => {
if (ref.current) setWidth(ref.current.offsetWidth)
}, [children])
return <div ref={ref}>{children} (width: {width}px)</div>
}
Common Mistakes
- Expecting ref updates to re-render the component
- Accessing
ref.currentduring render for DOM measurements (use layout effect or callback refs) - Passing refs as regular props without
forwardRefin custom components - Storing state in refs to avoid re-renders when UI should update
See Also
use-state use-effect use-callback components