🎣 React Hooks – In-Depth
Estimated reading: 4 minutes 26 views

🎣 React useRef Hook – DOM Access & Mutable Refs (2025 Guide)


🧲 Introduction – Why Use useRef?

In React.js, most data changes should flow through state and props. However, sometimes you need to interact with DOM elements directly or store values that persist across renders without causing re-renders. That’s where the useRef hook comes in.

The useRef hook gives you a mutable object whose .current property persists across re-renders β€” perfect for working with the DOM, timeouts, scroll positions, form focus, and more.

🎯 In this guide, you’ll learn:

  • What the useRef hook is and how it works
  • How to use useRef for DOM access and value persistence
  • Real-world examples and common use cases
  • Best practices and pitfalls to avoid

🧩 What is the useRef Hook?

useRef is a React Hook that returns a ref object:

const myRef = useRef(initialValue);
  • myRef.current holds a mutable value
  • Unlike state, updating myRef.current does NOT trigger a re-render

🧱 1. Accessing DOM Elements with useRef

React assigns the ref to the current property once the DOM is rendered.

βœ… Example – Focusing an Input:

import { useRef } from 'react';

function FocusInput() {
  const inputRef = useRef();

  const handleClick = () => {
    inputRef.current.focus();
  };

  return (
    <>
      <input ref={inputRef} type="text" placeholder="Click the button to focus" />
      <button onClick={handleClick}>Focus Input</button>
    </>
  );
}

πŸ“Œ ref={inputRef} attaches the reference to the DOM element
βœ… Great for managing focus, selection, or scroll behavior


πŸ” 2. Persisting Values Without Re-Rendering

Sometimes you need to persist a value between renders without re-rendering when it changes.

βœ… Example – Store Previous Value:

import { useEffect, useRef, useState } from 'react';

function PreviousCounter() {
  const [count, setCount] = useState(0);
  const prevCountRef = useRef();

  useEffect(() => {
    prevCountRef.current = count;
  });

  return (
    <>
      <p>Now: {count}, Before: {prevCountRef.current}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </>
  );
}

βœ… prevCountRef.current updates after each render
βœ… But the update itself doesn’t trigger a new render


πŸ§ͺ 3. useRef vs useState

FeatureuseRefuseState
Triggers re-render❌ Noβœ… Yes
Mutable storageβœ… Yes (ref.current)βœ… Yes (setState)
DOM accessβœ… Common use case❌ Not for DOM
Async-safe persistenceβœ… Good for setInterval, timers⚠️ Requires useEffect or memo

πŸ•’ 4. Using useRef for Timers and Intervals

βœ… Example – Clear an Interval:

function Timer() {
  const timerRef = useRef();

  const startTimer = () => {
    timerRef.current = setInterval(() => {
      console.log('Tick');
    }, 1000);
  };

  const stopTimer = () => {
    clearInterval(timerRef.current);
  };

  return (
    <>
      <button onClick={startTimer}>Start</button>
      <button onClick={stopTimer}>Stop</button>
    </>
  );
}

βœ… useRef stores interval IDs without rerenders


🧱 5. Forwarding Refs to Child Components

Sometimes you want to expose a ref from a child component to a parent.

βœ… Example:

const MyInput = React.forwardRef((props, ref) => {
  return <input ref={ref} {...props} />;
});

function App() {
  const inputRef = useRef();
  return <MyInput ref={inputRef} />;
}

πŸ“˜ Use forwardRef to allow parent access to child DOM nodes


⚠️ 6. Common Pitfalls

MistakeFix
Expecting re-render on .current updateUse useState instead
Using ref without ref.current checkAlways check before accessing DOM
Misunderstanding its async behaviorRemember refs persist across renders

πŸ“˜ Best Practices

βœ… Use useRef to:

  • Focus or scroll to DOM elements
  • Store mutable values like timers or counters
  • Avoid triggering renders with frequent changes

❌ Don’t use useRef when you need to reflect changes in the UI β€” use useState instead


πŸ“Œ Summary – Recap & Next Steps

The useRef hook is the Swiss Army knife for handling DOM nodes and persistent mutable values in React. It’s especially useful for accessing elements, tracking values between renders, and managing imperatively controlled behaviors like focus and timers.

πŸ” Key Takeaways:

  • useRef() returns a mutable ref object
  • Use it to access DOM nodes with ref={...}
  • Useful for storing values across renders without causing re-renders
  • Combine with useEffect() for lifecycle-driven logic
  • Avoid using useRef for state that needs to update the UI

βš™οΈ Real-World Relevance:
Used in forms, modals, animations, timers, and integrations where you need direct DOM access or non-reactive persistence (e.g., debounce, scroll tracking).


❓ FAQ Section

❓ Does updating a ref with useRef re-render the component?
❌ No. That’s one of the key benefits β€” useRef stores mutable data without triggering renders.


❓ When should I use useRef over useState?
βœ… Use useRef when:

  • You want to avoid re-renders
  • You need to access the DOM directly
  • You need to store a value across renders (e.g., previous value, timeout ID)

❓ Can I use useRef to focus an input?
βœ… Yes! Simply attach it to the ref prop and call ref.current.focus().


❓ What is .current in useRef?
βœ… .current is the actual value or DOM node held by the ref object.


❓ Can I use useRef with custom components?
βœ… Yes, but only if that component uses forwardRef internally.


Share Now :

Leave a Reply

Your email address will not be published. Required fields are marked *

Share

🎣 React useRef Hook – DOM & Mutable Refs

Or Copy Link

CONTENTS
Scroll to Top