useRef
useRef creates a mutable object holding a .current property that persists across renders without triggering re-renders.
Mental Model
"The Secret Notebook: You jot down phone numbers in your pocket notebook without broadcasting a public speech every time you write."
Interactive Engine Simulation
Invariant:The stability of this sequence is what allows React to persist state across asynchronous render cycles.
Executable Code Snippet
1function Stopwatch() {
2 const [now, setNow] = useState(null);
3 // useRef keeps a stable value between renders
4 // but changing it DOES NOT trigger a re-render
5 const intervalRef = useRef(null);
6
7 function handleStart() {
8 setNow(Date.now());
9 intervalRef.current = setInterval(() => {
10 setNow(Date.now());
11 }, 10);
12 }
13
14 return <button onClick={handleStart}>Start</button>;
15}- 01.Component re-renders are triggered by state or prop changes.
- 02.Reconciliation algorithm diffs the Virtual DOM to minimize actual DOM updates.
- 03.Automatic batching optimizes multiple state updates into a single render cycle.
01. Persistence without Noise
`useRef` returns a mutable ref object whose `.current` property is persisted throughout the full lifetime of the component. The key difference from `useState` is that **modifying .current does not trigger a re-render**. It's a secret box where you can store data that the UI doesn't need to know about.
Reference vs State
02. Accessing the Physical DOM
The most common use case for `useRef` is accessing a DOM node directly. When you pass a ref to a JSX element like `<div ref={myRef} />`, React sets `myRef.current` to that DOM node once it's mounted. This allows you to call native methods like `.focus()`, `.play()`, or `.scrollTo()`.
Expert Rule
"Do not use refs for things that can be done declaratively. If you're using a ref to hide/show a component, you're doing it wrong. Use refs for 'Imperative' tasks that React can't handle out of the box."