How to Get Component Width in React

As a developer building complex React dashboards for FinTech firms, I’ve often hit a common roadblock.

Standard CSS media queries are great, but sometimes you need the exact pixel width of a component to render a dynamic chart or a responsive data table.

Whether you are building a real-time stock ticker or a custom navigation bar, knowing the container size is crucial for a polished UI.

In this tutorial, I will show you exactly how to get a component’s width in React using the most reliable methods I use in production.

Why You Might Need a Component’s Width

While flexbox and grid handle most layouts, certain high-end UI components require programmatic width values.

For instance, if you are building a localized weather widget for a Chicago-based travel app, you might need to toggle between a compact and expanded view based on the div size.

I have also used these techniques to calculate the number of visible items in a horizontal scroll menu for a California-based e-commerce storefront.

Method 1: Use the useRef and useEffect Hooks

This is the easiest way to grab the width after the initial render. It is perfect for static elements that don’t change size after the page loads.

I typically use this when I need to initialize a third-party library, like a D3.js map, that requires a fixed width.

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

// Example: A Mortgage Calculator Container for a US Banking App
const MortgageWidget = () => {
  const containerRef = useRef(null);
  const [width, setWidth] = useState(0);

  useEffect(() => {
    if (containerRef.current) {
      // offsetWidth includes borders and padding
      const currentWidth = containerRef.current.offsetWidth;
      setWidth(currentWidth);
      console.log("Initial Widget Width:", currentWidth);
    }
  }, []);

  return (
    <div 
      ref={containerRef} 
      style={{ 
        width: '100%', 
        maxWidth: '800px', 
        margin: '20px auto', 
        padding: '20px', 
        border: '1px solid #ddd',
        backgroundColor: '#f9f9f9' 
      }}
    >
      <h2>US Home Loan Calculator</h2>
      <p>Current Container Width: <strong>{width}px</strong></p>
      <div style={{ height: '100px', background: '#004a99', color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        {width > 500 ? "Desktop View: Showing Full Amortization Table" : "Mobile View: Showing Summary Only"}
      </div>
    </div>
  );
};

export default MortgageWidget;

I executed the above example code and added the screenshot below.

Component Width in React

In this code, we attach a ref to the div. Once the component mounts, useEffect triggers, allowing us to read offsetWidth.

Method 2: Handle Window Resizes

If your users frequently flip their iPhones or resize their Chrome browsers, Method 1 will fail because it only runs once.

I remember building a real-time election map for a news outlet where the SVG had to scale perfectly as the user adjusted their window.

To solve this, we need to add an event listener to the window object.

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

const ResponsiveAdBanner = () => {
  const bannerRef = useRef(null);
  const [bannerWidth, setBannerWidth] = useState(0);

  const updateWidth = () => {
    if (bannerRef.current) {
      setBannerWidth(bannerRef.current.getBoundingClientRect().width);
    }
  };

  useEffect(() => {
    // Set initial width
    updateWidth();

    // Add event listener for window resize
    window.addEventListener('resize', updateWidth);

    // Clean up the listener to prevent memory leaks
    return () => window.removeEventListener('resize', updateWidth);
  }, []);

  return (
    <div ref={bannerRef} style={{ width: '90%', margin: '0 auto', background: '#eee', padding: '15px' }}>
      <h3>Texas State Fair - Early Bird Tickets</h3>
      <p>The current width of this promotional banner is: {Math.round(bannerWidth)}px</p>
      {bannerWidth < 400 ? (
        <button style={{ width: '100%' }}>Buy Now</button>
      ) : (
        <button style={{ padding: '10px 40px' }}>Secure Your Tickets Today</button>
      )}
    </div>
  );
};

export default ResponsiveAdBanner;

I executed the above example code and added the screenshot below.

Get Component Width in React

Using getBoundingClientRect().width is often more precise than offsetWidth as it handles sub-pixel values and CSS transforms.

Method 3: The Modern Way with ResizeObserver

Window resize listeners are okay, but they are inefficient. They trigger even if the specific component doesn’t change size (e.g., if a sidebar collapses).

The ResizeObserver API is a game-changer. It watches the specific element rather than the whole window.

I used this extensively while building a modular dashboard for a logistics company in Seattle.

import React, { useState, useLayoutEffect, useRef } from 'react';

const DeliveryTracker = () => {
  const [width, setWidth] = useState(0);
  const targetRef = useRef(null);

  useLayoutEffect(() => {
    if (!targetRef.current) return;

    const observer = new ResizeObserver((entries) => {
      for (let entry of entries) {
        // Use contentRect for the most accurate measurement
        setWidth(entry.contentRect.width);
      }
    });

    observer.observe(targetRef.current);

    return () => observer.disconnect();
  }, []);

  return (
    <div ref={targetRef} style={{ border: '2px dashed #333', padding: '20px', resize: 'horizontal', overflow: 'auto' }}>
      <h4>FedEx Shipment Tracker (Drag corner to resize)</h4>
      <p>Tracking ID: 12345-67890-USA</p>
      <div style={{ fontSize: width < 300 ? '12px' : '18px', transition: '0.3s' }}>
        Current Width: {Math.floor(width)}px
      </div>
    </div>
  );
};

export default DeliveryTracker;

I executed the above example code and added the screenshot below.

How to Get Component Width in React

I prefer useLayoutEffect here because it fires synchronously after all DOM mutations. This prevents the “flicker” you sometimes see with useEffect.

Method 4: Create a Reusable useComponentSize Custom Hook

In a large-scale project, you don’t want to rewrite the observer logic ten times. Clean code is a priority for me, so I always abstract this into a custom hook.

Here is a robust hook I’ve used across multiple US-based SaaS projects.

import { useState, useLayoutEffect, useCallback } from 'react';

const useComponentSize = () => {
  const [size, setSize] = useState({ width: 0, height: 0 });
  const [node, setNode] = useState(null);

  const ref = useCallback((newNode) => {
    if (newNode !== null) {
      setNode(newNode);
    }
  }, []);

  useLayoutEffect(() => {
    if (!node) return;

    const measure = () => {
      const { width, height } = node.getBoundingClientRect();
      setSize({ width, height });
    };

    const observer = new ResizeObserver(() => measure());
    observer.observe(node);

    return () => observer.disconnect();
  }, [node]);

  return [ref, size];
};

// Usage Example: A real estate listing card for a Miami brokerage
const PropertyCard = () => {
  const [componentRef, { width }] = useComponentSize();

  return (
    <div ref={componentRef} style={{ background: '#fff', boxShadow: '0 4px 8px rgba(0,0,0,0.1)', borderRadius: '8px' }}>
      <img 
        src="https://images.unsplash.com/photo-1512917774080-9991f1c4c750" 
        alt="Miami Luxury Home" 
        style={{ width: '100%', height: width > 400 ? '300px' : '150px', objectFit: 'cover' }}
      />
      <div style={{ padding: '15px' }}>
        <h3>$2,450,000 - Luxury Villa</h3>
        <p>Container Width: {Math.round(width)}px</p>
        {width > 350 && <p>Located in the heart of South Beach, Florida.</p>}
      </div>
    </div>
  );
};

export default PropertyCard;

Using a callback ref instead of useRef ensures that the hook re-calculates correctly even if the underlying DOM node changes.

Method 5: Use getBoundingClientRect for One-Off Calculations

Sometimes you don’t need to track the width; you just need to know what it is at a specific moment, like when a user clicks a “Print Report” button.

I used this recently for a tax software application based in California to ensure the PDF generation layout matched the screen width.

import React, { useRef } from 'react';

const TaxReportGenerator = () => {
  const reportRef = useRef(null);

  const handlePrint = () => {
    if (reportRef.current) {
      const dimensions = reportRef.current.getBoundingClientRect();
      alert(`The report width is ${dimensions.width}px. Optimizing for 1040-ES layout...`);
      // Proceed with print logic
    }
  };

  return (
    <div style={{ padding: '30px', textAlign: 'center' }}>
      <div ref={reportRef} style={{ border: '1px solid black', padding: '50px', marginBottom: '10px' }}>
        <h1>2025 IRS Tax Summary</h1>
        <p>This is a confidential document for US Taxpayers.</p>
      </div>
      <button onClick={handlePrint} style={{ backgroundColor: '#d32f2f', color: 'white', padding: '10px 20px', border: 'none', cursor: 'pointer' }}>
        Generate Optimized Report
      </button>
    </div>
  );
};

export default TaxReportGenerator;

This method is lightweight because it avoids state updates and observers entirely.

Key Differences: offsetWidth vs. getBoundingClientRect

Choosing the right property is a common point of confusion.

offsetWidth returns an integer and includes the element’s padding, scrollbar, and border.

getBoundingClientRect().width returns a precise floating-point number and is usually what you want for high-precision layouts.

In my experience, if you are working with CSS transforms like scale(), getBoundingClientRect is the only one that returns the visually rendered width.

Getting the component width in React is a foundational skill for building truly responsive web applications.

Whether you use a simple ref or a complex ResizeObserver, always remember to clean up your listeners to keep your app performing smoothly.

You may also like to read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.