Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 1 of the Intermediate React: Hooks, State & Data Patterns course
ReactJune 25, 20264 min read

Mastering useRef for DOM Access in React

Learn how to use the useRef hook to interact with DOM nodes and persist mutable values without triggering re-renders in your React applications.

ReactuseRefhooksDOMfrontendintermediatejavascript

Previously in this course, we explored how to manage component lifecycles in React lifecycle: Mastering Mounting, Updating, and Unmounting. While state is the primary way to drive your UI, sometimes you need to break out of that paradigm to talk directly to the browser.

useRef is your "escape hatch." It allows you to hold a reference to a DOM node or keep track of a value that doesn't need to trigger a re-render when it changes. In this lesson, we’ll move beyond theoretical state and start interacting with the browser's imperative DOM API.

Understanding useRef from First Principles

In React, we usually rely on state to update the DOM. When state changes, React re-renders the component and updates the DOM to match. However, there are times when you need to access a DOM element directly—like focusing an input, scrolling to a specific div, or integrating a third-party library that expects a raw DOM node.

A ref is a plain JavaScript object with a single property: current. When you pass this ref to a React element via the ref attribute, React automatically sets the current property to the corresponding DOM node once the component mounts.

Crucially, updating the .current property does not trigger a re-render. This makes useRef perfect for:

  1. DOM access: Storing a reference to an element.
  2. Mutable storage: Holding values (like timers or previous state) that shouldn't cause the UI to flicker when updated.

Worked Example: Managing Focus and Scroll

In our dashboard project, we often need to ensure the user can quickly interact with search inputs. Let’s build a search component that focuses the input automatically and scrolls to a specific results container.

JSX
import { useRef } from CE9178">'react';

function DashboardSearch() {
  // 1. Initialize the ref with null
  const inputRef = useRef(null);
  const scrollContainerRef = useRef(null);

  const handleFocus = () => {
    // 2. Access the DOM node via .current
    inputRef.current.focus();
  };

  const handleScroll = () => {
    // 3. Imperative DOM manipulation
    scrollContainerRef.current.scrollIntoView({ behavior: CE9178">'smooth' });
  };

  return (
    <div>
      <input ref={inputRef} type="text" placeholder="Search dashboard..." />
      <button onClick={handleFocus}>Focus Input</button>
      
      <div style={{ height: CE9178">'200vh' }}>
        <button onClick={handleScroll}>Scroll to Bottom</button>
        <div ref={scrollContainerRef}>Target Section</div>
      </div>
    </div>
  );
}

In this example, inputRef and scrollContainerRef are created during the initial render. Because they are persistent containers, they remain the same object throughout the lifecycle of the component. When the component mounts, React assigns the DOM elements to the current property.

Hands-on Exercise

To solidify your understanding, add a "Clear and Focus" button to your current dashboard search bar.

  1. Create a ref for your search input.
  2. Create an onClick handler that clears the input's value by accessing inputRef.current.value = ''.
  3. Immediately call inputRef.current.focus() after clearing the value.
  4. Observe how you are bypassing React’s state-driven update flow to force an imperative change.

Note: In production, you would typically use controlled components for inputs, but understanding this "uncontrolled" approach is vital for integrating non-React libraries.

Common Pitfalls

While useRef is powerful, it’s easy to misuse:

  • Reading/Writing during render: Do not read or write to ref.current during the main body of your component function. Only do it inside useEffect or event handlers. Accessing it during render can cause unpredictable behavior if React's rendering process changes.
  • Assuming the ref is ready: Always check if ref.current is not null before calling methods like .focus() or .scrollIntoView(). If your component conditionally renders the element, the ref might be null.
  • Overusing refs for UI state: If you find yourself using useRef to store information that should affect what the user sees, you probably want useState instead. As we discussed in React useRef and Component Memory: Why Variables Reset on Re-render, refs are for "hidden" data, not data that drives the UI.

Recap

useRef is a specialized tool. Use it when you need to bridge the gap between React's declarative world and the browser's imperative DOM APIs. Remember:

  • It returns an object { current: ... }.
  • Updating it does not trigger a re-render.
  • It is the standard way to handle focus, scroll, and integration with third-party DOM libraries.

By mastering useRef, you gain the control necessary to build truly interactive, complex dashboard widgets that go beyond simple data binding.

Up next: We will dive deeper into persistent mutable values and how to use refs to track previous prop values without stale closures.

Next lesson Persistent Mutable Values with useRef
Back to Blog

Similar Posts

ReactJune 25, 20264 min read

Persistent Mutable Values with useRef: Managing React State

Learn to use useRef for persistent mutable values that don't trigger re-renders. Master tracking props and solving stale closures in your React projects.

Read more
ReactJune 25, 20263 min read

Optimizing Function References with useCallback in React

Learn how to use useCallback to stabilize function identities, prevent unnecessary child re-renders, and master dependency arrays in your React components.

Part of the course

Intermediate React: Hooks, State & Data Patterns

intermediate · Lesson 1 of 48

  1. 1

    Mastering useRef for DOM Access

    4 min
  2. 2

    Persistent Mutable Values with useRef

    4 min
  3. 3

    Memoizing Expensive Calculations with useMemo

    3 min
Read more
ReactJune 25, 20263 min read

Memoizing Expensive Calculations with useMemo for Performance

Learn how to use the useMemo hook to cache expensive calculations in React. Stop redundant re-renders and keep your dashboard UI fast and responsive.

Read more
  • 4

    Optimizing Function References with useCallback

    3 min
  • 5

    Introduction to Custom Hooks

    4 min
  • 6

    Building a useLocalStorage Hook

    4 min
  • 7

    Refactoring Dashboard Settings

    4 min
  • 8

    Complex State with useReducer

    3 min
  • 9

    Managing Object-Based State

    3 min
  • 10

    Introduction to Context API

    Coming soon
  • 11

    Architecting Global State with Context and Reducer

    Coming soon
  • 12

    Implementing Theme Context

    Coming soon
  • 13

    Structuring State for Performance

    Coming soon
  • 14

    Handling Authentication State

    Coming soon
  • 15

    Integrating Reducers with Auth State

    Coming soon
  • 16

    Introduction to React Router

    Coming soon
  • 17

    Dynamic Routing with URL Parameters

    Coming soon
  • 18

    Nested Routes and Layouts

    Coming soon
  • 19

    Protected Routes for Authenticated Views

    Coming soon
  • 20

    Programmatic Navigation

    Coming soon
  • 21

    Building the Dashboard Navigation Structure

    Coming soon
  • 22

    Asynchronous Data Lifecycle

    Coming soon
  • 23

    Caching Strategies with React Query

    Coming soon
  • 24

    Mutations and Data Updates

    Coming soon
  • 25

    Synchronizing Client and Server State

    Coming soon
  • 26

    Integrating Live Data into the Dashboard

    Coming soon
  • 27

    Error Handling and Loading UI

    Coming soon
  • 28

    Controlled vs Uncontrolled Components

    Coming soon
  • 29

    Real-time Form Validation

    Coming soon
  • 30

    Schema-based Validation with Zod

    Coming soon
  • 31

    Handling Multi-step Forms

    Coming soon
  • 32

    Optimizing Form Submissions

    Coming soon
  • 33

    Performance Profiling with React DevTools

    Coming soon
  • 34

    Refactoring for Scalability

    Coming soon
  • 35

    Finalizing Dashboard Data Flow

    Coming soon
  • 36

    Deploying the Application

    Coming soon
  • 37

    Advanced Hook Composition

    Coming soon
  • 38

    Implementing Middleware for State

    Coming soon
  • 39

    Advanced Context Patterns

    Coming soon
  • 40

    Router Loaders and Data Prefetching

    Coming soon
  • 41

    Complex Route Guards

    Coming soon
  • 42

    Handling Large Datasets in UI

    Coming soon
  • 43

    Testing Hooks and Components

    Coming soon
  • 44

    Managing Global Modals

    Coming soon
  • 45

    Implementing Keyboard Shortcuts

    Coming soon
  • 46

    Optimizing Asset Loading

    Coming soon
  • 47

    Internationalization Basics

    Coming soon
  • 48

    Managing WebSocket Connections

    Coming soon
  • View full course