React › Refs, useRef & forwardRef

How is useRef different from useState when it comes to storing a value?

Intermediate

Answer

Updating a value with useState causes the component to re render so the screen reflects the new value. Updating a ref's value using useRef does not cause any re render at all, making it useful for values you need to remember between renders but that should never directly affect what is shown on screen, like tracking a previous value or a timer id.
function Timer() {
  const intervalRef = useRef(null);
  const [seconds, setSeconds] = useState(0);

  function startTimer() {
    intervalRef.current = setInterval(() => setSeconds((s) => s + 1), 1000);
  }

  function stopTimer() {
    clearInterval(intervalRef.current);
  }

  return <button onClick={startTimer}>Start</button>;
}
Real-world example A stopwatch component stores its timer id using useRef, since the id itself never needs to appear on screen, while the actual elapsed seconds are stored using useState so the display updates correctly.

Common follow-ups: What would happen if you stored the timer id using useState instead of useRef?;When would you actually want changing a value to trigger a re render versus not?