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:
Feature | useRef | useState |
---|---|---|
Purpose | To persist a mutable value without causing re-renders. | To manage state in a functional component that causes re-renders when updated. |
Initial Value | useRef (initialValue ) | useState (initialValue ) |
Return Value | An object with a .current property. | An array with the current state value and a function to update it. |
Re-renders | Does not cause re-renders when .current is updated. | Causes re-renders when the state is updated. |
Use Case | Accessing DOM elements directly, storing mutable values, and holding previous values. | Managing component state that affects rendering. |
Value Persistence | Persists between renders. | Persists between renders. |
Update Method | Directly update .current property. | Use the setter function provided by useState . |
Example Usage | Accessing an input element: inputRef .current.focus () | Counter: const [count, |
Common Scenario | Storing instance variables, and handling side effects that don’t need re-rendering. | Managing form inputs, toggling UI elements, and holding any stateful data. |
Reactivity | Not reactive. Changes to .current are not tracked by React. | Reactive. Changes to state trigger component re-rendering. |
Reset Behavior | Not 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 accessDOM
elements directly and manage mutable states without causing unnecessary re-renders.