stackademic

The leading education platform for anyone with an interest in software development.

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.current during render for DOM measurements (use layout effect or callback refs)
  • Passing refs as regular props without forwardRef in custom components
  • Storing state in refs to avoid re-renders when UI should update

See Also

use-state use-effect use-callback components