React useRef() hook and ref prop - Small guide

What is useRef()?

Those with some experience in early versions of React, have probably used the ref prop as a way to access elements in the DOM. This was important in a bunch of use cases. For example: (1) managing focus, text selection or media playback, (2) triggering animations, (3) integrate with third-party DOM libraries.

Newer versions of React brings the useRef() hook which creates a mutable object that will persists its values for the full lifetime of the component, in other words, even between renders of the component.

Let's have a closer look at this hook.

How to use useRef() to access DOM elements?

Quite simple:

  1. Import useRef from React.
  2. Declare the reference.
  3. Assign the reference to the ref attribute of the element.
  4. Done! Now the .current property will hold the DOM element and can be accessed in any event of the component lifecycle or method.

In code:

No alt text provided for this image

In the snippet above, I'm importing useRef in line 1.

In line 4, I'm declaring the reference. This reference is assigned to the ref attribute of the element in line 17.

The onButtonClick function is an example of how the DOM element can be accessed via .current property.

Also, in lines 6 and 7, I'm demonstrating how the DOM element can be accessed in any side effect.

Do you need to keep a mutable value around? Use useRef()

useRef() hook can be used for more than just keeping reference of DOM elements.

useRef() creates a plain JavaScript object. The only difference between useRef() and creating a { current: ... } javascript object, is that useRef will provide the same ref object on every render.

So, an initial value can be assigned when useRef is declared and this value can be read or updated at will, since it's mutable.

This is often illustrated by a simple use case: storing the number of clicks on a button.

Here it is the snippet:

No alt text provided for this image

You will notice that in line 4, along with the useRef declaration, I'm assigning an initial value.

Then, in the onLoginClick handler (line 6), the mutable object (and its current property) can be modified (adding one every time it's called, line 7, countRef.current++). And also can be easily read, as shown in line 8 (countRef.current).

At this point you might think I can do the same with useState, so What's the difference?.

You are right. In fact, the "counting clicks" use case is often used to explain the useState hook.

There are two important differences:

  1. When the state of a component is updated via useState hook, a render will be triggered. On the other hand, when a reference is updated, no render is triggered.
  2. Updating the state is an asynchronous call (the state is updated after re-render). On the other hand, a reference is updated synchronously, in other words, the value is available right away.


Have you used useRef for a different use case?


To view or add a comment, sign in

More articles by Ronny Delgado

  • Domain Events - DDD, Clean Architecture

    Domain Events play a crucial role in maintaining clean, loosely coupled architectures in C#. They enable effective…

  • Functional programming - The Basics

    Although Functional Programming has been around for decades, it has taken a new boost in recent years. In this post I…

Explore content categories