Hookshigh

useRef

useRef returns a mutable object { current: value } that persists across renders without causing re-renders when mutated. It's commonly used to hold DOM element references and mutable instance variables.

Memory anchor

useRef is a locker at the gym — you can store things between workouts (renders), grab them anytime, and nobody else notices when you swap the contents.

Expected depth

Unlike state, changing ref.current does NOT trigger a re-render. This makes refs ideal for storing values that need to persist (like interval IDs, previous state values, or imperative API handles) without the overhead of re-rendering. When passed as a ref prop to a JSX element, React sets ref.current to the DOM node after mount and null on unmount. forwardRef (or the ref prop in React 19) lets child components expose their DOM nodes to parents.

Deep — senior internals

Refs are stored on the fiber just like state, but they're exempt from the reconciliation comparison. React processes ref attachments during the commit phase — after all DOM mutations — so ref.current always points to the committed DOM. useImperativeHandle combined with forwardRef lets you customize what the parent sees, exposing an API object instead of the raw DOM node. In concurrent mode, refs may point to stale DOM during the render phase; only read refs in effects or event handlers, never during render.

🎤Interview-ready answer

useRef gives me a mutable container that persists across renders without triggering re-renders. I use it for DOM access, storing interval IDs, and keeping mutable values like previous props. The key rule is to never read or write refs during render in concurrent mode — only in effects and event handlers.

Common trap

Reading ref.current during render can cause bugs in concurrent mode because the ref might point to a DOM node from a different render. Always access refs inside useEffect or event handlers.