Understanding the useRef Hook in React
Sudhanshu Gaikwad
Posted on October 10, 2024
The useRef
Hook is an essential tool in React that allows us to store values between renders, directly access DOM elements, and avoid unnecessary re-renders. It’s often compared to the useState
Hook but serves a different purpose.
What is the
useRef
Hook?
The useRef
Hook creates a reference to a value or DOM element that persists between component renders. The key difference between useRef
and useState
is that updating the useRef
value does not trigger a re-render, which can be particularly useful in certain scenarios.
- It does not cause re-renders when its value changes.
- It can be used to store mutable values.
- It can be used to directly access DOM elements.
Basic Syntax
const refContainer = useRef(initialValue);
Example 1: Persisting Values Between Renders
import React, { useRef, useEffect } from "react";
function RenderCount() {
const renderCount = useRef(1);
useEffect(() => {
renderCount.current = renderCount.current + 1;
});
// Inline styles
const containerStyle = {
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100vh",
backgroundColor: "#f4f4f4",
};
const headingStyle = {
fontSize: "2rem",
color: "#333",
fontFamily: "Arial, sans-serif",
backgroundColor: "#fff",
padding: "20px",
borderRadius: "8px",
boxShadow: "0 4px 8px rgba(0, 0, 0, 0.1)",
};
return (
<div style={containerStyle}>
<h1 style={headingStyle}>
This component has rendered {renderCount.current} times.
</h1>
</div>
);
}
export default RenderCount;
Output
Example 2: Accessing DOM Elements
import React, { useState, useRef } from "react";
function Timer() {
const [seconds, setSeconds] = useState(0);
const intervalRef = useRef(null);
// Start the timer
const startTimer = () => {
if (!intervalRef.current) {
intervalRef.current = setInterval(() => {
setSeconds((prevSeconds) => prevSeconds + 1);
}, 1000);
}
};
// Stop the timer
const stopTimer = () => {
clearInterval(intervalRef.current);
intervalRef.current = null;
};
// Reset the timer
const resetTimer = () => {
stopTimer();
setSeconds(0);
};
// Inline styles
const timerContainerStyle = {
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
height: "100vh",
backgroundColor: "#f0f2f5", // Light neutral background
};
const timerDisplayStyle = {
fontSize: "3rem",
color: "#2c3e50", // Dark blue-gray for a professional look
};
const buttonStyle = {
padding: "10px 20px",
margin: "10px",
fontSize: "1rem",
backgroundColor: "#2980b9", // Professional blue
color: "white",
border: "none",
borderRadius: "5px",
cursor: "pointer",
transition: "background-color 0.3s ease-in-out",
};
const buttonHoverStyle = {
backgroundColor: "#1a5276", // Darker shade for hover effect
};
return (
<div style={timerContainerStyle}>
<h1 style={timerDisplayStyle}>{seconds} seconds</h1>
<div>
<button
style={buttonStyle}
onClick={startTimer}
onMouseOver={(e) => (e.currentTarget.style.backgroundColor = buttonHoverStyle.backgroundColor)}
onMouseOut={(e) => (e.currentTarget.style.backgroundColor = buttonStyle.backgroundColor)}
>
Start
</button>
<button
style={buttonStyle}
onClick={stopTimer}
onMouseOver={(e) => (e.currentTarget.style.backgroundColor = buttonHoverStyle.backgroundColor)}
onMouseOut={(e) => (e.currentTarget.style.backgroundColor = buttonStyle.backgroundColor)}
>
Stop
</button>
<button
style={buttonStyle}
onClick={resetTimer}
onMouseOver={(e) => (e.currentTarget.style.backgroundColor = buttonHoverStyle.backgroundColor)}
onMouseOut={(e) => (e.currentTarget.style.backgroundColor = buttonStyle.backgroundColor)}
>
Reset
</button>
</div>
</div>
);
}
export default Timer;
Output
When to Use
useRef
Instead ofuseState
Here are some scenarios where useRef
is more appropriate than useState
:
When you need to store a value that doesn’t need to trigger a re-render when updated (e.g., timers, counters, or tracking renders).
When you need to directly access or modify DOM elements without causing a re-render.
Posted on October 10, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 22, 2024