What is useRef and When Should You Use It?
In React, not all data needs to trigger a re-render. That's where useRef comes in. It allows you to persist mutable values across renders without causing re-renders, and it's also your tool for directly accessing DOM elements.
✅ What is useRef?
useRef is a React hook that returns a mutable object with a .current property.
const ref = useRef(initialValue);
- The
ref.current value persists across renders.
- Updating
ref.current does NOT cause the component to re-render.
- Often used to reference DOM nodes or store imperative values.
🧰 Common Use Cases for useRef
1. Accessing DOM Elements
If you want to manipulate or focus an input element, useRef gives you direct access.
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus(); // Automatically focus on mount
}, []);
return <input ref={inputRef} />;
2. Storing Previous Values
Track the previous state or prop without triggering re-renders.
const prevCount = useRef();
useEffect(() => {
prevCount.current = count;
}, [count]);
3. Avoiding Re-Renders for Mutable Values
Use useRef to store timers, intervals, or any variable that doesn't affect UI directly.
const timerRef = useRef(null);
4. Preventing Re-Initialization
If you need a value to persist between renders (like a singleton), useRef helps avoid re-initializing.
const idRef = useRef(generateUniqueId());
❓ useRef vs useState: What's the Difference?
| Feature |
useState |
useRef |
| Triggers re-render |
✅ Yes |
❌ No |
| DOM access |
❌ No |
✅ Yes |
| Stores values |
✅ Yes |
✅ Yes (without UI sync) |
| Common uses |
UI state, logic |
DOM refs, previous values |
⚠️ Gotchas to Avoid
- Don't use
useRef for reactive state. If the UI depends on a value, use useState.
- Be careful with stale refs. Since refs persist, outdated logic inside effects can lead to bugs.
🧩 Pro Tip
Use useRef along with useEffect to track values between renders without causing unnecessary UI updates.
✅ Conclusion
Use useRef in React, when you need to:
- Access or modify a DOM element directly
- Store a value that persists across renders but doesn’t affect the UI
- Avoid performance issues with frequent re-renders
It’s a powerful, lightweight tool—especially when combined with useEffect or useImperativeHandle.