React useRef Hook

Summary: in this tutorial, you will learn about the React useRef hook to access DOM elements directly and persist values between renders.

Introduction to the React useRef hook

In React, the useRef hook allows you to access a DOM element directly like document.querySelector() in plain JavaScript. Additionally, the useRef hook lets you modify a state without causing a re-render.

Here are the steps for using the useRef hook:

Step 1. Import useRef from React:

import React, { useRef } from 'react';Code language: JavaScript (javascript)

Step 2. Creating the ref object:

Call the useRef() function with an initial value to create a ref object:

const myRef = useRef(initialValue);Code language: JavaScript (javascript)

The return of the useRef() function is a mutable object MyRef.

It means that updating the ref’s value will not cause a re-render. This is the main difference between the useRef and useState hooks.

Step 3. Attach the ref object to a DOM element.

Attach the ref to a DOM element using the ref attribute if you want to access the DOM element directly:

<input ref={myRef} type="text" />Code language: JavaScript (javascript)

Step 4. Use the ref object.

Access the current value of the ref via the .current property inside the event handlers, effect hooks, or any other part of your component:

const handleClick = () => {
  console.log(myRef.current.value);
};Code language: JavaScript (javascript)

Step 5. Update the ref

Update the .current property of the ref object to change its value without causing a re-render:

myRef.current = newValue;Code language: JavaScript (javascript)

React useRef hook usages

In practice, you’ll use the useRef() hook to directly access DOM elements or manage mutable objects without causing a re-render.

Accessing DOM elements directly

The following component shows how to use the useRef hook to access DOM elements directly:

import { useRef } from 'react';

const SubscriberForm = () => {
  const inputRef = useRef(null);

  const handleClick = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <label htmlFor="email">Email:</label>
      <input type="email" id="email" ref={inputRef} />
      <button type="submit" onClick={handleClick}>
        Submit
      </button>
    </div>
  );
};

export default SubscriberForm;
Code language: JavaScript (javascript)

The SubscriberForm has an input element and a button. When you click the button, the input will get the focus.

How it works.

First, import useRef from the react:

import { useRef } from 'react';Code language: JavaScript (javascript)

Second, declare a ref object with an initial value of null:

const inputRef = useRef(null);Code language: JavaScript (javascript)

Third, attach the ref object to the ref attribute of the input:

<input type="email" id="email" ref={inputRef} />Code language: JavaScript (javascript)

When React renders the component, it will set the current property of the ref object to the input ( DOM node). You can access the methods of the DOM node like focus().

Finally, set the focus to the input element when the user clicks the submit button by calling the focus() method of the DOM element:

const handleClick = (e) => {
  inputRef.current.focus();
};Code language: JavaScript (javascript)

Storing mutable values

The following example shows how to use the ref to store a mutable value that persists across renders without triggering a re-render:

import { useRef } from 'react';

const Counter = () => {
  const countRef = useRef(0);

  const incrementCount = () => {
    countRef.current++;
    alert(countRef.current);
  };

  return <button onClick={incrementCount}>Increment Count</button>;
};

export default Counter;Code language: JavaScript (javascript)

How it works.

First, import useRef from the react library:

import { useRef } from 'react';Code language: JavaScript (javascript)

Second, return a countRef from the useRef() hook with an initial value of 0:

const countRef = useRef(0);Code language: JavaScript (javascript)

Third, increase the value of the ref when the user clicks the button:

const incrementCount = () => {
  countRef.current++;
  alert(countRef.current);
};Code language: JavaScript (javascript)

useRef vs. useState hook

The following table highlights the differences between useRef and useState hooks:

FeatureuseRefuseState
PurposeTo persist a mutable value without causing re-renders.To manage state in a functional component that causes re-renders when updated.
Initial ValueuseRef(initialValue)useState(initialValue)
Return ValueAn object with a .current property.An array with the current state value and a function to update it.
Re-rendersDoes not cause re-renders when .current is updated.Causes re-renders when the state is updated.
Use CaseAccessing DOM elements directly, storing mutable values, and holding previous values.Managing component state that affects rendering.
Value PersistencePersists between renders.Persists between renders.
Update MethodDirectly update .current property.Use the setter function provided by useState.
Example UsageAccessing an input element: inputRef.current.focus()Counter: const [count, setCount] = useState(0)
Common ScenarioStoring instance variables, and handling side effects that don’t need re-rendering.Managing form inputs, toggling UI elements, and holding any stateful data.
ReactivityNot reactive. Changes to .current are not tracked by React.Reactive. Changes to state trigger component re-rendering.
Reset BehaviorNot resettable through state changes; retains value unless explicitly changed.State can be reset through setter function or re-initialized on component re-mount.

Summary

  • Utilize the useRef() hook to access DOM elements directly and manage mutable states without causing unnecessary re-renders.
Was this tutorial helpful ?