Accessing the DOM with React's useRef Hook

Gain a direct line to the DOM and manage persistent values without triggering re-renders.

Welcome! Sometimes we need to interact directly with an element, like focusing an input. Let's see how `useRef` helps.

/* Preparing to bridge React and the DOM... */

What is `useRef`?

The useRef hook returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component. It's like a "box" that can hold a value which isn't part of the component's state.

Accessing DOM Elements

The most common use case for useRef is to access a DOM element directly. You create a ref, attach it to a JSX element via the `ref` attribute, and after the component mounts, `myRef.current` will point to the actual HTML element. This is perfect for managing focus, triggering animations, or integrating with DOM-based libraries.

Storing Mutable Values Without Re-rendering

useRef can also hold any mutable value, similar to an instance property on a class. The key difference from state is that updating a ref does not trigger a re-render. This makes it ideal for storing information that needs to persist between renders but doesn't affect the visual output, such as timer IDs or previous state values.

The Result: A Bridge to the Imperative World

By mastering useRef, you gain a powerful tool to break out of React's declarative flow when necessary. It provides a direct, imperative bridge to the DOM and a way to manage persistent values without the overhead of state updates, enabling more complex interactions and performance optimizations.

Practice Zone


Interactive Test 1: Match the Concept

Match the useRef code snippet to its correct description.

Arrastra en el orden correspondiente.


Arrastra las opciones:

myRef.current.focus()
const myRef = useRef(null);
<input ref={myRef} />

Completa el código:

Creating a Ref______
Attaching a Ref______
Accessing the Value______
Unlock with Premium

Interactive Test 2: Complete the Code

Rellena los huecos en cada casilla.

function FocusInput() {
  const inputEl = (null);

  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.?.focus();
  };

  return (
    <>
      <input ={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}
Unlock with Premium

Practice Example: Code Editor

Create a component that plays a video when a "Play" button is clicked and pauses it when a "Pause" button is clicked. Use useRef to get a reference to the video element.

Enunciado:

* Escribe el código a continuación. Los caracteres correctos se mostrarán en verde y los incorrectos en rojo.

function VideoPlayer() { const videoRef = useRef(null); const handlePlay = () => { videoRef.current.play(); }; const handlePause = () => { videoRef.current.pause(); }; return ( <div> <video ref={videoRef} src="https://www.w3schools.com/html/mov_bbb.mp4" width="320" height="176" /> <button onClick={handlePlay}>Play</button> <button onClick={handlePause}>Pause</button> </div> ); }

Unlock with Premium

Knowledge Check

What is the primary consequence of changing the `.current` property of a ref object?


Unlock with Premium

useRef in Action

useRef is your go-to tool when you need to interact with the DOM directly or persist values without causing re-renders. Here are some common practical scenarios.


1. Managing Focus and Media Playback

Programmatically controlling focus on form inputs or triggering play/pause on a video element are classic examples. useRef gives you direct access to the element's imperative API.

const videoRef = useRef(null);

const handlePlay = () => {
  videoRef.current.play();
}

2. Measuring DOM Elements

Sometimes you need to know the size or position of an element after it has rendered, perhaps for a tooltip or a custom layout. You can use a ref in a `useEffect` hook to read these properties.

const myDivRef = useRef(null);

useEffect(() => {
  if (myDivRef.current) {
    const width = myDivRef.current.offsetWidth;
    console.log('Component width:', width);
  }
}, []);
Width: 150px

3. Storing Previous State

How do you know what the value of a prop or state was in the *previous* render? useRef is perfect for this. You can update the ref's `.current` value at the end of your render cycle.

const prevCountRef = useRef();

useEffect(() => {
  prevCountRef.current = count;
}); // Runs AFTER every render

const prevCount = prevCountRef.current;

Current: 5

Previous: 4


Practical Takeaway: Think of useRef as a component's "backpack". It can carry tools (DOM nodes) and memories (previous values) that it needs for its journey, without having to announce every change to the world (by re-rendering).

useRef Glossary

useRef
A React Hook that lets you reference a value that’s not needed for rendering. It returns a mutable object with a single `.current` property.
Ref Object
The object returned by useRef. It has one property: `current`. You can change `ref.current` to store new information.
`.current` property
The property on the ref object that holds the actual value. If the ref is attached to a DOM node, `ref.current` will be the DOM node itself. This property is mutable.
`ref` attribute
A special prop available on all JSX elements. You pass a ref object to it (e.g., <div ref=myRef /> ) to instruct React to put the corresponding DOM node into `myRef.current`.
Imperative Code
Code that specifies the exact steps to get a result (e.g., `video.play()`). React is primarily "declarative" (you describe the desired UI), but useRef provides an "escape hatch" to write imperative code when needed.