useRef in React
Written By: Avinash Malhotra
Updated on
In React, most data is managed by states. But sometimes, you need to store values that don't cause re-renders or directly access DOM elements. That's where the useRef hook comes in.
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.
What is useRef?
The useRef hook is a built-in React hook that allows you to create a mutable reference that persists across re-renders of a functional component. It is commonly used to access and manipulate DOM elements directly, store mutable values, and maintain references to previous values without causing re-renders.
The value stored in ref.current persists across renders, but changing it does not re-render the component.
import { useRef } from "react";
const ref = useRef(initialValue); // initial value
ref.current = newValue; // update value
In this example, we import the useRef hook from React and create a ref object using useRef(initialValue). The initial value is set to initialValue. You can access or update the current value of the ref using ref.current.
The useRef hook is particularly useful in scenarios where you need to:
- Access and manipulate DOM elements directly, such as focusing an input field or measuring its dimensions.
- Store mutable values that don't require re-rendering, like timers or previous state values.
- Maintain references to previous values without causing re-renders.
Accessing DOM Elements
You can use useRef to directly access and control DOM elements, like focusing an input field.
Here's an example:
import { useRef } from "react";
function FocusInput() {
const inputRef = useRef(null);
const handleFocus = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleFocus}>Focus Input</button>
</div>
);
}
In this example, the FocusInput component uses the useRef hook to create a reference to the input element. The handleFocus function is called when the button is clicked, which uses the ref to focus the input field.
Storing Values Without Re-render
The useRef hook can also be used to store values without causing re-renders. This is particularly useful for storing mutable values that don't need to trigger a re-render when updated.
Here's an example:
import { useRef, useState } from "react";
function RenderCounter() {
const [count, setCount] = useState(0);
const renders = useRef(0);
renders.current = renders.current + 1;
return (
<div>
<p>Count: {count}</p>
<p>Component rendered: {renders.current} times</p>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
}
In this example, the Timer component uses the useRef hook to store a mutable count value. The handleIncrement function increments the count stored in countRef.current. To reflect the updated count in the UI, we use a dummy state variable ignored and call forceUpdate to trigger a re-render.
Storing Previous Value
You can use the useRef hook to store the previous value of a state or prop without causing re-renders.
Here's an example:
import { useState, useEffect, useRef } from "react";
function PreviousValueExample() {
const [count, setCount] = useState(0);
const prevCount = useRef();
useEffect(() => {
prevCount.current = count;
}, [count]);
return (
<div>
<p>Current: {count}</p>
<p>Previous: {prevCount.current}</p>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
}
In this example, the PreviousValue component uses the useRef hook to store the previous value of the count state. The useEffect hook updates the ref with the current count value whenever it changes. The previous count value is then accessed using prevCountRef.current.
Summary
- useRef is used for:
- Accessing DOM elements (focus, scroll, etc.).
- Storing values across renders without re-rendering.
- Keeping track of previous values.
- Unlike state, changing ref.current does not cause re-renders.