All topics
Advancedintermediate

Refs and the DOM Escape Hatch

Understand refs as React's deliberate escape hatch for imperative DOM access, and where the boundary between declarative and imperative code should sit.

React's entire model is declarative — you describe what the UI should look like given the current state, and React handles the imperative work of updating the actual DOM to match. Refs are the officially sanctioned escape hatch for the specific cases where imperative access genuinely is needed: focusing an input, measuring an element's size, integrating a non-React library that expects a real DOM node, or triggering an animation.

Refs are like a building's emergency exit: the normal, everyday flow of people (declarative rendering) goes through the main doors according to clear signage and rules, but the emergency exit (a ref) exists deliberately for the specific, narrower set of situations that genuinely need to bypass that normal flow — using the emergency exit as your regular daily entrance defeats the purpose of having an orderly main entrance at all.

Key Concepts

1
The boundary matters because reaching for imperative ref-based code where a declarative prop/state-driven approach would work just as well tends to produce harder-to-follow code that doesn't fit React's overall mental model — for example, imperatively toggling a CSS class via a ref instead of deriving className from state fights against, rather than works with, how React expects UI to be described.
className
2
Legitimate ref use cases share a common trait: they involve something outside of what 'render as a function of state' can naturally express — you can't declaratively express 'focus this input right now' as a prop, since focus is a transient, imperative action rather than persistent visual state. Recognizing this distinction (declarative-expressible state vs. genuinely imperative actions) is the core skill in deciding when a ref is the right tool.
3
Interviewers ask candidates to critique code that overuses refs for things that could be expressed declaratively (like manually toggling visibility via ref.current.style.display instead of conditional rendering based on state) versus legitimate uses (focusing an input after a validation error), testing judgment about React's underlying philosophy rather than just ref API mechanics.
ref.current.style.display