Understanding useRef in React
useRef is one of the built-in Hooks in React that allows us to store a value that persists between component renders. The main difference between useRef and useState is that changing a ref value does not cause the component to re-render. Because of this, useRef is useful when we want React to remember a value, but we do not want that value change to update the UI. A ref can also be used to directly access a DOM element, such as an input, button, or div.
How useRef Works
We create a ref by calling useRef():
const inputRef = useRef(null);
useRef() returns an object containing a current property. We access or change the stored value using .current.
inputRef.current
One important thing to understand is that useRef does not store the value directly in the variable itself. Instead, the value is stored inside the current property. The ref object remains the same between renders, which means the value stored in .current can be remembered even when the component renders again.
A common use of useRef is accessing a DOM element. In normal JavaScript, we can use document.getElementById() to get a reference to an HTML element. React provides ref as a cleaner way to get a reference to an element.
import { useRef } from "react";
function App() {
const inputRef = useRef(null);
function focusInput() {
inputRef.current.focus();
}
return (
<>
<input ref={inputRef} />
<button onClick={focusInput}>
Focus Input
</button>
</>
);
}
Here, ref={inputRef} tells React to connect the input element with the ref. After React creates the input element, the actual DOM element becomes available through inputRef.current. Therefore, when inputRef.current.focus() is called, JavaScript is accessing the actual input element and calling its focus() method.
Another important feature of useRef is that its value persists between renders. A normal variable declared inside a component can be recreated whenever the component renders. A ref, however, keeps the same ref object between renders, so its .current value can be used to remember information.
const countRef = useRef(0);
countRef.current++;
If the component renders again, the value stored in countRef.current is still available. However, changing countRef.current does not tell React to render the component again. This is one of the biggest differences between useRef and useState.
With state:
const [count, setCount] = useState(0);
setCount(10);
React schedules a re-render because the state is normally used to control what appears on the screen. With a ref:
const countRef = useRef(0);
countRef.current = 10;
React does not re-render because changing a ref is intended for storing information rather than updating the UI.
This gives us a simple rule for deciding between them. Use useState when changing a value should update the UI. Use useRef when you need to remember a value without causing a re-render. For example, a counter displayed on the screen should normally use state, while a timer ID that only needs to be remembered so it can later be stopped can be stored in a ref.
const timerRef = useRef(null);
timerRef.current = setInterval(() => {
console.log("Running...");
}, 1000);
clearInterval(timerRef.current);
Here, the timer ID does not need to be displayed on the screen. We only need to remember it so that we can later pass it to clearInterval(). Therefore, a ref is suitable.
It is important not to think of useRef as a replacement for useState. They have different purposes. If you store a value in a ref and then display that value in JSX, changing the ref alone will not update what the user sees. If the UI needs to react to the value changing, state is generally the correct choice.
In simple terms, useRef can be thought of as a persistent storage box inside a React component. The value inside the box is available through .current, it survives re-renders, and changing it does not trigger another render. This makes useRef especially useful for DOM references, timer IDs, previous values, and other information that React needs to remember but that does not directly control the UI.
Final Difference
useState
↓
Value changes
↓
React re-renders
↓
UI can update
useRef
↓
.current changes
↓
No re-render
↓
Value is simply remembered
The most important idea to remember is: useState is mainly for data that affects the UI, while useRef is mainly for data or references that need to persist without causing the UI to re-render.
Top comments (0)