useRef Hook
useRef = mutable value that persists across renders
What is useRef?
"Mutable ref object"
useRef returns a mutable ref object that persists across renders without causing re-renders.
"useRef returns a mutable ref object that persists across renders, useful for DOM references or storing mutable values that don't trigger re-renders."
Basic Syntax
useRef(initialValue)
const inputRef = useRef(null);
Returns object with .current property.
"useRef takes an initial value and returns a ref object with a current property."
DOM References
Access DOM elements
function Component() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return (
<>
<input ref={inputRef} />
<button onClick={focusInput}>Focus</button>
</>
);
}
"useRef is commonly used to access DOM elements by passing the ref to the ref prop."
Storing Mutable Values
Values that don't trigger re-renders
function Component() {
const countRef = useRef(0);
const increment = () => {
countRef.current += 1; // No re-render
console.log(countRef.current);
};
return <button onClick={increment}>Count: {countRef.current}</button>;
}
"useRef can store mutable values that persist across renders without causing re-renders when updated."
useRef vs useState
useRef = no re-render, useState = re-render
| Feature | useRef | useState |
|---|---|---|
| Re-render on change | ❌ | ✅ |
| Persists across renders | ✅ | ✅ |
| Mutable | ✅ | ❌ (immutable) |
| Use for | DOM, timers | UI state |
"useRef doesn't trigger re-renders when current changes, while useState does. useRef is mutable, useState is immutable."
Common Use Cases
DOM access · Timers · Previous values
- DOM manipulation: Focus, scroll, measurements
- Timers: Store interval/timeout IDs
- Previous values: Track previous props/state
- Imperative APIs: Third-party library integration
"useRef is used for DOM access, storing timer IDs, tracking previous values, and imperative APIs."
Storing Previous Values
Track previous props/state
function Component({ count }) {
const prevCountRef = useRef();
useEffect(() => {
prevCountRef.current = count;
});
const prevCount = prevCountRef.current;
return (
<div>
Previous: {prevCount}, Current: {count}
</div>
);
}
"useRef can store previous values by updating ref.current in useEffect without dependencies."
Timer Management
Store interval/timeout IDs
function Component() {
const intervalRef = useRef();
useEffect(() => {
intervalRef.current = setInterval(() => {
console.log("Tick");
}, 1000);
return () => clearInterval(intervalRef.current);
}, []);
}
"useRef stores timer IDs for cleanup, preventing memory leaks from intervals or timeouts."
9️⃣ Multiple Refs
Create multiple refs
const input1Ref = useRef(null);
const input2Ref = useRef(null);
const input3Ref = useRef(null);
"Components can use multiple useRef calls for different refs."
Ref Callback Pattern
Function refs for dynamic refs
function Component() {
const [refs, setRefs] = useState([]);
const setRef = (element) => {
if (element) {
setRefs((prev) => [...prev, element]);
}
};
return items.map((item) => (
<div key={item.id} ref={setRef}>
{item.name}
</div>
));
}
"Callback refs allow dynamic ref management, useful for lists or conditional refs."
"useRef returns a mutable ref object that persists across renders without causing re-renders. It's used for DOM references, storing mutable values, timer IDs, and tracking previous values. Unlike useState, updating ref.current doesn't trigger re-renders. Common use cases include DOM manipulation, imperative APIs, and storing values that shouldn't cause re-renders."
🧠 Ultra-Short Cheat Sheet
Mutable ref object
Persists across renders
No re-render on change
DOM references
Store mutable values
Timer IDs
Previous values
useRef vs useState