Skip to content

useRef Hook

useRef returns a mutable object { current: value } that persists across renders. Changing .current does not trigger a re-render. Use it for DOM access, timer IDs, and any mutable value that shouldn't cause updates.

Two Uses of useRef

DOM refs: attach to JSX via ref={myRef} to imperatively focus inputs, measure elements, or integrate with non-React libraries.

Instance variables: store previous values, interval IDs, or flags without adding render cycles.

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

  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  return <input ref={inputRef} />;
}

Optional chaining handles null before mount.

useRef vs useState

const ref = useRef(0);
ref.current += 1;  // no re-render

const [n, setN] = useState(0);
setN(n + 1);       // triggers re-render
  • Updating ref.current never re-renders the component.
  • Do not read/write refs during render for UI decisions.
  • Initialize with null for DOM refs.
  • Use forwardRef to pass refs through wrapper components.

useRef Patterns

Common ref use cases in React apps.

Use Case Pattern
Focus input inputRef.current.focus()
Store timer ID timerRef.current = setInterval(...)
Previous value prevRef.current = value in effect
Avoid stale closure Mutable ref for latest callback
DOM measurement ref.current.getBoundingClientRect()
Uncontrolled input Read ref.current.value

Tracking Previous Props/State

Store the previous value in a ref updated in an effect to compare changes across renders.

const prevCount = useRef();
useEffect(() => { prevCount.current = count; });
const increased = count > (prevCount.current ?? 0);

forwardRef Basics

Parent components sometimes need refs to child DOM nodes. forwardRef lets a wrapper component pass a ref to an inner element.

const FancyInput = forwardRef(function FancyInput(props, ref) {
  return <input ref={ref} className="fancy" {...props} />;
});

Common Mistakes

  • Expecting ref updates to refresh the UI.
  • Accessing DOM refs before mount (null).
  • Using refs to store data that should trigger renders.
  • Forgetting forwardRef when wrapping native inputs in libraries.

Key Takeaways

  • useRef holds mutable values across renders without re-rendering.
  • Primary uses: DOM access and instance-like variables.
  • Use forwardRef to expose inner DOM nodes from components.
  • Do not substitute refs for state that affects UI.

Pro Tip

React 19 improves ref handling — you can often pass ref as a regular prop without forwardRef in newer codebases.