useRef Is React's Most Underrated Hook — It Handles DOM, Force Renders, and Web Workers
Misusing useState for non-UI data causes unnecessary renders that degrade performance in animations, real-time streams, and worker-heavy apps. Recognizing when a value should live in a ref instead of state is a cheap, high-leverage fix that every React developer can apply immediately.
React's useRef returns a plain `{ current }` container. Mutating `.current` never schedules a re-render, which separates it from useState. That property makes it the correct home for DOM node references, where a ref paired with useEffect replaces autoFocus with programmatic control at any lifecycle moment. The same non-reactive storage enables a forceRender pattern: a useState setter stripped of its state value acts as a manual refresh trigger, letting a ref accumulate high-frequency updates that only flush to the UI in batches. Web Worker instances fit the same model. A Worker runs off the main thread and has no business driving UI, so stashing it in a ref avoids pointless re-renders while keeping the reference alive across renders.
Many React beginners treat useRef as a niche DOM-access trick, but its core capability — non-reactive mutable storage — is a general-purpose primitive that solves a class of performance problems useState can't touch.
The forceRender pattern effectively repurposes a useState setter as a manual `requestRender()` call, which isn't documented as an official API but falls naturally out of how React's scheduler works.
Storing a Worker in useRef highlights a broader rule: any object whose lifecycle is independent of the UI tree (timers, sockets, WASM instances, third-party lib handles) should live in a ref to avoid coupling it to React's render cycle.