Understanding useRef in React

🧠Data Structures and Algorithms | Python | Java | FullStack Development | Open Source
A Guide to Managing References Without Re-renders
In React, one of the most powerful hooks available is useRef. This hook allows us to persist values between renders without triggering a re-render, making it an essential tool for managing certain types of data that don't belong in the component's state.
In this blog, we'll explore what refs are, how to use useRef, and provide an example to illustrate its behavior.
What is a Ref?
A ref stands for "reference." Essentially, it's like a box into which you can put any data that you want to preserve between renders.
When we use the useRef hook, React gives us an object with a mutable current property, which we can use to store any data we want. Unlike state, updating this current property will not trigger a re-render.
Key Characteristics of useRef
Persistent Data:
useRefis useful for storing data that you want to keep around across renders, but which doesn't directly affect the UI. For example, tracking the previous value of a prop or managing a timer ID.Not Rendered in JSX:
useRefis typically used for values that are not part of the rendered output, meaning you generally use it within event handlers or side effects (likeuseEffect). If you want to display or use values within your JSX, it's better to use state.No Re-renders: A crucial difference between refs and state is that updating a ref's
currentvalue does not cause a re-render. This makesuseRefideal for managing things like DOM elements or other mutable values that change over time but shouldn’t force a component update.
Best Practices
- Avoid Reading/Writing
currentin Render Logic: Unlike state, refs should not be read or written during the render phase of the component. Doing so can lead to unexpected behavior or hard-to-debug issues, as the ref's value can change without causing the component to update.
Code Example: Using useRef to Manage a DOM Element
Here's an example of how to use useRef to interact with a DOM element without triggering re-renders.
import React, { useRef } from "react";
function TextInputFocus() {
// Create a ref to store the text input DOM element
const inputRef = useRef(null);
const handleFocus = () => {
// Access the input's DOM node and focus on it
if (inputRef.current) {
inputRef.current.focus();
}
};
return (
<div>
<input ref={inputRef} type="text" placeholder="Click the button to focus" />
<button onClick={handleFocus}>Focus the Input</button>
</div>
);
}
export default TextInputFocus;
Explanation:
We create a ref using
useRef(null), and assign it to the input element withref={inputRef}.The
handleFocusfunction, triggered by the button click, uses the ref to access the input element's DOM node and focus on it. This operation does not cause a re-render because we're only modifying the DOM element, not the component state.
When Should You Use useRef?
Accessing DOM elements: As shown in the example,
useRefis perfect for interacting with DOM elements directly.Storing mutable data: If you need to store some data that changes over time but doesn’t affect the UI (like a timer ID or previous prop value),
useRefis the right choice.Preserving values between renders: Since
useRefpersists data across renders without causing updates, it's a great tool for maintaining non-UI-related values.
Important Notes
Refs don’t cause re-renders: Unlike state, updating a ref’s
currentproperty won’t re-render the component. This makes refs useful for avoiding unnecessary UI updates when only non-rendering logic is affected.State for UI updates, refs for side effects: When working with values that affect the UI, use state. For everything else—like tracking timers, storing previous values, or interacting with DOM nodes—use refs.
By understanding and properly using useRef, you can avoid unnecessary re-renders and handle mutable values efficiently in your React components.
Feel free to test out the example and see how you can apply useRef in your own projects! Happy coding! 😊



