Refs (useRef)
Definition
The `useRef` hook returns a mutable ref object whose `.current` property is initialized to the passed argument. It is used to persist values across renders without causing a re-render, or to directly access DOM elements.
Explain Like I'm New
Imagine you have a sticky note on your desk. `useState` is like writing a number on the main whiteboard (everyone sees it, and writing on it stops the whole class). `useRef` is like writing a number on your private sticky note. You can change it secretly as much as you want, and the teacher (React) will never stop the class (re-render) because of it.
Real World Example
You want a text input to automatically be focused (cursor blinking) when a modal opens. You use `useRef` to grab the actual HTML `<input>` element and call `inputRef.current.focus()`.
Common Use Cases
- •Directly accessing and manipulating DOM elements (focus, measuring size)
- •Storing mutable values that shouldn't trigger re-renders (like a timer ID)
- •Keeping track of previous state values
Interactive Example
import React, { useRef, useState } from 'react'; export default function StopWatch() { const [time, setTime] = useState(0); // We use a ref to store the interval ID. // If we used state for this, setting it would cause an unnecessary re-render! const timerIdRef = useRef(null); const start = () => { if (timerIdRef.current) return; // Prevent multiple clicks timerIdRef.current = setInterval(() => setTime(t => t + 1), 1000); }; const stop = () => { clearInterval(timerIdRef.current); timerIdRef.current = null; }; return ( <div> <h2>Stopwatch: {time}s</h2> <button onClick={start}>Start</button> <button onClick={stop}>Stop</button> </div> ); }
Interview Questions
basic
- What is the primary difference between `useState` and `useRef`?
- How do you attach a ref to a DOM element?
intermediate
- If you update `myRef.current = 5`, will the component re-render?
- When is the `.current` property attached to the DOM element?
advanced
- What is `forwardRef` and when do you need it?
- Can you use `useRef` inside a custom hook to prevent stale closures?
trick
- Is `useRef(initialValue)` the same as `{ current: initialValue }`?