useRef

useRef holds a mutable value or a reference to a DOM node without re-rendering.

Syntaxconst inputRef = useRef(null);

useRef returns a mutable object with a .current property. Changing .current does not trigger a re-render, which makes refs useful for two things.

Common uses

  • DOM access — attach a ref to an element to focus it, measure it, or play media.
  • Persisting a value across renders without causing re-renders, like a timer id or previous value.

Example

Example · javascript
import { useRef } from 'react';

function SearchBox() {
  const inputRef = useRef(null);
  function focusInput() {
    inputRef.current.focus();
  }
  return (
    <div>
      <input ref={inputRef} placeholder="Search..." />
      <button onClick={focusInput}>Focus</button>
    </div>
  );
}

When to use it

  • An auto-focus field uses useRef to call .focus() on an input element the moment a modal opens, without the user needing to click.
  • A video player component holds a ref to the <video> element so imperative play/pause methods can be called from a custom control bar.
  • A debounce hook stores the timer ID in a ref so it persists across re-renders without triggering extra renders when the timer is reset.

More examples

Focus an input on mount

Attaches a ref to an input element and calls focus() after mount without causing any extra renders.

Example · jsx
import { useRef, useEffect } from 'react';

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

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

  return <input ref={inputRef} placeholder="Start typing..." />;
}

Store mutable value without re-render

Stores the interval ID in a ref so it persists across renders without triggering them when updated.

Example · jsx
import { useState, useRef } from 'react';

function StopWatch() {
  const [elapsed, setElapsed] = useState(0);
  const intervalRef = useRef(null);

  const start = () => {
    intervalRef.current = setInterval(
      () => setElapsed(e => e + 1), 1000
    );
  };

  const stop = () => clearInterval(intervalRef.current);

  return (
    <div>
      <p>{elapsed}s</p>
      <button onClick={start}>Start</button>
      <button onClick={stop}>Stop</button>
    </div>
  );
}

Track previous prop value

Uses a ref updated in useEffect to remember the value from the previous render for comparison.

Example · jsx
import { useRef, useEffect } from 'react';

function usePrevious(value) {
  const ref = useRef(undefined);
  useEffect(() => { ref.current = value; });
  return ref.current;
}

function PriceDisplay({ price }) {
  const prevPrice = usePrevious(price);
  const direction = price > prevPrice ? 'up' : 'down';
  return <p className={direction}>${price}</p>;
}

Discussion

  • Be the first to comment on this lesson.