or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-react-use-measure

React hook utility for measuring DOM element boundaries with reactive updates

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-use-measure@2.1.x

To install, run

npx @tessl/cli install tessl/npm-react-use-measure@2.1.0

index.mddocs/

React Use Measure

React Use Measure is a utility React hook for measuring DOM element boundaries with reactive updates. It provides precise position and size information that accounts for scroll containers and viewport changes, solving the common problem of getting accurate element positioning in dynamic React applications.

Package Information

  • Package Name: react-use-measure
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install react-use-measure

Core Imports

import useMeasure from "react-use-measure";
import type { RectReadOnly, Options } from "react-use-measure";

For CommonJS:

const useMeasure = require("react-use-measure");
// For accessing the default export specifically:
// const useMeasure = require("react-use-measure").default;

Basic Usage

import React from "react";
import useMeasure from "react-use-measure";

function MyComponent() {
  const [ref, bounds] = useMeasure();

  return (
    <div>
      <div ref={ref}>
        Measure me!
      </div>
      <p>
        Size: {bounds.width}x{bounds.height}
        Position: ({bounds.left}, {bounds.top})
      </p>
    </div>
  );
}

Architecture

React Use Measure is built around several key components:

  • ResizeObserver Integration: Uses the browser's ResizeObserver API to detect element size changes
  • Scroll Tracking: Optional monitoring of scroll events in nested containers and viewport
  • Debouncing System: Configurable debouncing for performance optimization
  • Polyfill Support: Injectable ResizeObserver polyfill for older browsers
  • Reactive Updates: Automatic state updates when element bounds change

Capabilities

Main Hook Function

The primary useMeasure hook provides DOM element measurement with reactive updates.

/**
 * React hook for measuring DOM element boundaries with reactive updates
 * @param options - Configuration options for measurement behavior (defaults: { debounce: 0, scroll: false, offsetSize: false })
 * @returns Tuple containing ref callback, bounds object, and force refresh function
 */
function useMeasure(options?: Options): [
  (element: HTMLOrSVGElement | null) => void,
  RectReadOnly,
  () => void
];

Usage Example:

import useMeasure from "react-use-measure";

function ResponsiveComponent() {
  const [ref, bounds, forceRefresh] = useMeasure({
    debounce: 100,
    scroll: true
  });

  // Use forceRefresh to manually trigger measurement
  const handleRefresh = () => {
    forceRefresh();
  };

  return (
    <div>
      <div ref={ref}>Content to measure</div>
      <button onClick={handleRefresh}>Force Refresh</button>
    </div>
  );
}

Advanced Configuration

Configure measurement behavior with debouncing, scroll tracking, and polyfill support.

interface Options {
  /** Debounce events in milliseconds or separate values for scroll/resize (default: 0) */
  debounce?: number | { scroll: number; resize: number };
  /** React to nested scroll changes - use with caution for performance (default: false) */
  scroll?: boolean;
  /** Inject a ResizeObserver polyfill for browser compatibility */
  polyfill?: { new (cb: ResizeObserverCallback): ResizeObserver };
  /** Use offsetWidth/offsetHeight instead of getBoundingClientRect for sizing (default: false) */
  offsetSize?: boolean;
}

Usage Example:

import useMeasure from "react-use-measure";
import { ResizeObserver } from "@juggle/resize-observer";

function AdvancedComponent() {
  const [ref, bounds] = useMeasure({
    debounce: { scroll: 50, resize: 100 },
    scroll: true,
    polyfill: ResizeObserver,
    offsetSize: true
  });

  return <div ref={ref}>Advanced measurement</div>;
}

Scroll Tracking

Enable scroll tracking to get accurate positioning within scroll containers.

// Enable scroll tracking for elements within scrollable containers
const [ref, bounds] = useMeasure({ scroll: true });

// With scroll tracking, bounds.top and bounds.left account for:
// - Page scroll position
// - Nested scroll container positions
// - Viewport changes

Debouncing Control

Control performance with debouncing options for scroll and resize events.

// Simple debouncing - same value for both scroll and resize
const [ref, bounds] = useMeasure({ debounce: 100 });

// Separate debouncing for scroll vs resize events
const [ref, bounds] = useMeasure({
  debounce: { scroll: 50, resize: 200 }
});

// No debouncing for immediate updates
const [ref, bounds] = useMeasure({ debounce: 0 });

Types

Bounds Object

interface RectReadOnly {
  /** X coordinate relative to viewport */
  readonly x: number;
  /** Y coordinate relative to viewport */
  readonly y: number;
  /** Element width in pixels */
  readonly width: number;
  /** Element height in pixels */
  readonly height: number;
  /** Distance from top edge of viewport */
  readonly top: number;
  /** Distance from right edge of viewport */
  readonly right: number;
  /** Distance from bottom edge of viewport */
  readonly bottom: number;
  /** Distance from left edge of viewport */
  readonly left: number;
  /** Index signature for additional numeric properties */
  [key: string]: number;
}

Hook Return Type

/** The return type of the useMeasure hook */
type UseMeasureResult = [
  /** Ref callback to attach to the element you want to measure */
  (element: HTMLOrSVGElement | null) => void,
  /** Current bounds/measurements of the element */
  RectReadOnly,
  /** Function to manually trigger a measurement update */
  () => void
];

Element Type Alias

/** Union type for HTML and SVG elements that can be measured */
type HTMLOrSVGElement = HTMLElement | SVGElement;

ResizeObserver Types

/** ResizeObserver callback function type */
type ResizeObserverCallback = (entries: any[], observer: ResizeObserver) => void;

/** ResizeObserver class declaration for polyfill compatibility */
declare class ResizeObserver {
  constructor(callback: ResizeObserverCallback);
  observe(target: Element, options?: any): void;
  unobserve(target: Element): void;
  disconnect(): void;
  static toString(): string;
}

Error Handling

The hook throws a descriptive error when ResizeObserver is not available:

// This will throw if ResizeObserver is not supported and no polyfill is provided
const [ref, bounds] = useMeasure();

// Error message: "This browser does not support ResizeObserver out of the box. 
// See: https://github.com/react-spring/react-use-measure/#resize-observer-polyfills"

// Solution: Provide a polyfill
import { ResizeObserver } from "@juggle/resize-observer";
const [ref, bounds] = useMeasure({ polyfill: ResizeObserver });

Performance Considerations

  • Debouncing: Use debouncing for frequently changing elements to avoid excessive re-renders
  • Scroll Tracking: Only enable scroll tracking when necessary, as it adds event listeners
  • Initial Render: Bounds will be zero on first render until the element is measured
  • Memory Leaks: The hook automatically cleans up observers and event listeners on unmount

Browser Compatibility

  • Modern Browsers: Works out of the box with native ResizeObserver support
  • Older Browsers: Requires ResizeObserver polyfill (recommended: @juggle/resize-observer)
  • React Version: Requires React 16.13 or higher
  • React-DOM: Optional peer dependency for SSR environments