React Hook to Measure Element Bounds

2.1.7 · active · verified Sun Apr 19

`react-use-measure` is a utility hook for React applications designed to precisely measure the bounding box of a referenced DOM element. It provides reactive updates to an element's dimensions and position (`x`, `y`, `width`, `height`, `top`, `right`, `bottom`, `left`), responding to changes in size, window scroll, and even nested scroll areas, which significantly differentiates it from standard `getBoundingClientRect`. This addresses a common challenge in web development where relative coordinates and offsets within complex scrollable layouts are difficult to ascertain reliably. The package is currently stable at version 2.1.7, with recent minor fix releases indicating active maintenance. It is part of the `pmndrs` ecosystem and leverages `ResizeObserver` for efficient updates. It ships with TypeScript types, promoting strong typing in projects.

Common errors

Warnings

Install

Imports

Quickstart

This example demonstrates how to use `useMeasure` to get reactive bounds of a resizable and scrollable div, including optional polyfill injection and debouncing of updates. It also shows how to access the `bounds` object after the initial render.

import useMeasure from 'react-use-measure';
import { useRef, useEffect } from 'react';
import { ResizeObserver } from '@juggle/resize-observer'; // Optional polyfill

function App() {
  const [ref, bounds] = useMeasure({
    // Optional: inject a polyfill if your target environments don't support ResizeObserver
    polyfill: typeof window !== 'undefined' && 'ResizeObserver' in window ? undefined : ResizeObserver,
    debounce: 100, // Debounce updates for performance
    scroll: true // React to scroll changes within parent elements
  });

  // Example of using the bounds in a side effect
  useEffect(() => {
    if (bounds.width > 0) {
      console.log('Element dimensions:', bounds.width, 'x', bounds.height);
    }
  }, [bounds]);

  return (
    <div style={{ padding: '20px', border: '1px solid #ccc', marginBottom: '20px' }}>
      <h1>ResizeObserver Hook Example</h1>
      <p>Resize your browser window or interact with the measured div.</p>
      <div
        ref={ref}
        style={{
          width: '50%',
          minHeight: '100px',
          background: 'lightblue',
          resize: 'both', // Allows manual resizing
          overflow: 'auto',
          margin: '20px auto',
          padding: '10px'
        }}
      >
        <p>This div is measured:</p>
        <p>Width: {bounds.width}px</p>
        <p>Height: {bounds.height}px</p>
        <p>Top: {bounds.top}px, Left: {bounds.left}px</p>
        <div style={{ height: '200px', width: '100%', background: 'lightcoral', marginTop: '10px' }}>
          Scrollable content inside.
          {Array.from({ length: 50 }).map((_, i) => <div key={i}>Item {i}</div>)}
        </div>
      </div>
      <div style={{ height: '500px', background: '#eee' }}>
        A larger container to enable page scrolling and demonstrate `scroll: true`.
      </div>
    </div>
  );
}

export default App;

view raw JSON →