The useRef
Hook in React is a versatile tool that allows developers to persist values between renders, access DOM elements directly, and store mutable values without triggering re-renders. In this guide, we'll explore how to use useRef
effectively with creative and dynamic examples.
useRef
?The useRef
Hook provides a way to manage persistent values across renders. Unlike useState
, updating a useRef
value does not cause the component to re-render. It also allows you to interact directly with DOM elements, bypassing React's abstraction when necessary.
useRef
Does Not Trigger Re-Renders: You can store values that change without affecting the render cycle.
Access DOM Elements Directly: Use useRef
to manipulate DOM elements when required.
Persist Previous State: Keep track of previous state values across renders.
useRef
Let’s count how many times a component renders, but without causing an infinite loop:
import { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom/client";
function RenderCounter() {
const [text, setText] = useState("");
const renderCount = useRef(0);
useEffect(() => {
renderCount.current += 1;
});
return (
<>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<h2>This component has rendered {renderCount.current} times!</h2>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<RenderCounter />);
Here, useRef
tracks the render count without causing additional re-renders. Try typing into the input field to see the count increase dynamically.
Using useRef
, you can directly focus an input field when a button is clicked:
import { useRef } from "react";
import ReactDOM from "react-dom/client";
function InputFocus() {
const inputRef = useRef();
const handleFocus = () => {
inputRef.current.focus();
};
return (
<>
<input type="text" ref={inputRef} placeholder="Click the button to focus me" />
<button onClick={handleFocus}>Focus Input</button>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<InputFocus />);
This example demonstrates how useRef
can be used for DOM manipulation while maintaining React's declarative nature.
Use useRef
to remember the previous value of a state:
import { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom/client";
function RememberPrevious() {
const [current, setCurrent] = useState("");
const previous = useRef("");
useEffect(() => {
previous.current = current;
}, [current]);
return (
<>
<input
type="text"
value={current}
onChange={(e) => setCurrent(e.target.value)}
/>
<h2>Current Value: {current}</h2>
<h2>Previous Value: {previous.current}</h2>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<RememberPrevious />);
By combining useState
, useEffect
, and useRef
, this example shows how to track the previous value of a state without unnecessary re-renders.
Here’s an example of using useRef
to measure the dimensions of an element:
import { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom/client";
function MeasureBox() {
const boxRef = useRef();
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
useEffect(() => {
const { offsetWidth, offsetHeight } = boxRef.current;
setDimensions({ width: offsetWidth, height: offsetHeight });
}, []);
return (
<>
<div
ref={boxRef}
style={{ width: "200px", height: "100px", background: "lightblue" }}
></div>
<h2>Width: {dimensions.width}px</h2>
<h2>Height: {dimensions.height}px</h2>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<MeasureBox />);
This example illustrates how useRef
can interact with DOM elements to retrieve information like dimensions.
useRef
Use it Sparingly: Rely on React's state and props for most use cases. Reserve useRef
for special cases like DOM manipulation or persisting values.
Avoid Replacing State: If a value requires re-rendering the UI, use useState
instead of useRef
.
Always Check .current
: Ensure the current
property is available before accessing it.
The useRef
Hook is a powerful addition to React's toolbox, offering flexibility for managing persistent values, interacting with the DOM, and remembering previous states. By understanding and experimenting with the examples above, you can unlock its full potential and add a new layer of interactivity to your React applications.
Start incorporating useRef
into your projects today and see how it simplifies your workflow!
The complete source code for this part is available on GitHub