In React, the useRef
hook is useful for interacting with the DOM and maintaining values across renders without causing re-renders.
In this post, you’ll learn everything about useRef, including how it works, its use cases, and best practices with examples.
Before we get started, don’t forget to subscribe to my newsletter!
Get the latest tips, tools, and resources to level up your web development skills delivered straight to your inbox. Subscribe here!
Now let’s jump right into it!🚀
What is useRef?
useRef
is a React Hook that returns a mutable reference object.
This reference persists across renders but does not trigger a re-render when updated. To put it simply, when a component’s state changes, React updates the UI by re-rendering the component. But useRef
stores values without triggering this update.
You can think of useRef
as a sticky note on your desk. You can update what’s written on it, but it doesn’t affect the layout of your desk. Similarly, useRef
stores a value without causing your component to refresh.
Why use useRef?
The useRef
hook is useful for:
- Accessing and modifying DOM elements directly.
- Storing values between renders without causing re-renders.
- Tracking previous values in a component.
Basic Syntax of useRef
Before using useRef
, you need to import it from React:
import { useRef } from "react";
Syntax:
const myRef = useRef(initialValue);
Here,
-
useRef(initialValue)
: Returns an object{ current: initialValue }
- The reference persists across renders but does not cause re-renders when updated.
- You can update the value using
myRef.current
.
For example:
import { useRef } from "react";
function Example() {
const countRef = useRef(0); // Creates a ref with initial value 0
const handleClick = () => {
countRef.current += 1; // Updates ref value (no re-render)
console.log("Current count:", countRef.current);
};
return (
<div>
<button onClick={handleClick}>Incrementbutton>
div>
);
}
Here,
-
countRef
is a mutable reference storing a value. - Clicking the button updates
countRef.current
, but the UI does not re-render. - The new value is logged in the console.
Use Case of useRef
Use Case 1: Accessing DOM Elements
If you need to access a DOM element directly without using document.querySelector
, you can use the useRef
hook.
Example: Setting focus on an input field
import { useRef } from "react";
function FocusInput() {
const inputRef = useRef(null); // Create Ref
const handleClick = () => {
inputRef.current.focus(); // This will focus on the input field
};
return (
<div>
<input ref={inputRef} type="text" placeholder="Enter text" />
<button onClick={handleClick}>Focus Inputbutton>
div>
);
}
export default FocusInput;
In this example,
-
useRef(null)
creates a reference to store the input element. -
ref={inputRef}
connects the reference to the input field. -
inputRef.current.focus()
sets focus on the input field when the button is clicked.
Use Case 2: Store Value Without Re-render
If you need to store a value without re-rendering a component, you can use the useRef
hook.
Example: Tracking the re-render count
import { useState, useRef, useEffect } from "react";
function RenderCounter() {
const [count, setCount] = useState(0);
const renderCount = useRef(0); // Mutable Value (This will not re-render)
useEffect(() => {
renderCount.current += 1; // Increment render count
});
return (
<div>
<p>Count: {count}p>
<p>Component Re-rendered: {renderCount.current} timesp>
<button onClick={() => setCount(count + 1)}>Incrementbutton>
div>
);
}
export default RenderCounter;
In this example,
-
renderCount
persists across renders without causing extra re-renders. - Using
useState
instead ofuseRef
here would cause an unnecessary re-render each timerenderCount
is updated.
Use Case 3: Track the previous value
You can use the useRef
hook to store the previous value of a state.
Example:
import { useState, useEffect, useRef } from "react";
function PreviousValueTracker() {
const [count, setCount] = useState(0);
const prevCountRef = useRef(); // This will store previous value
useEffect(() => {
prevCountRef.current = count; // Update Previous Value
}, [count]);
return (
<div>
<p>Current Count: {count}p>
<p>Previous Count: {prevCountRef.current}p>
<button onClick={() => setCount(count + 1)}>Incrementbutton>
div>
);
}
export default PreviousValueTracker;
Here,
-
prevCountRef
stores the previous value ofcount
. -
useEffect
updatesprevCountRef.current
whenevercount
changes.
useRef vs useState: When to use?
Feature | useRef | useState |
---|---|---|
Value Persistence | Yes, persists across renders | Yes, persists across renders |
Re-render Trigger | No re-render on update | Triggers re-render |
Use Case | DOM access, previous values | UI updates, state management |
Initial Value | { current: initialValue } | Any data type supported |
- If you need to update the UI, use the
useState
hook. - If you need to store a value without triggering a re-render, use the
useRef
hook.
Best Practices & Common Mistakes of useRef
Mistake: Using useRef for UI updates
const countRef = useRef(0);
const increment = () => {
countRef.current += 1;
console.log(countRef.current); // This will update the value, but not the UI
};
Best Practice: For UI updates, use the useState
hook.
Mistake: Using useRef
for executing side effects
function App() {
const ref = useRef(0);
if (ref.current === 0) {
console.log("Component mounted!"); // This will execute multiple times
}
ref.current++;
}
Here, useRef
values persist between renders, but component re-renders don’t reset their value. So the condition (if (ref.current === 0))
will always be true on re-render, causing repeated execution.
Best Practice: Use the useEffect
hook for side effects.
Example:
useEffect(() => {
console.log("Component mounted!");
}, []);
Why You Need useRef?
- Efficiently access DOM elements.
- Store values across renders without unnecessary re-renders.
- Track previous state values.
🎯Wrapping Up
That’s all for today!
For paid collaboration connect with me at : [email protected]
I hope this post helps you.
If you found this post helpful, here’s how you can support my work:
☕ Buy me a coffee – Every little contribution keeps me motivated!
📩 Subscribe to my newsletter – Get the latest tech tips, tools & resources.
𝕏 Follow me on X (Twitter) – I share daily web development tips & insights.
Keep coding & happy learning!