mwui
GitHub

useResizeObserver

A hook that measures an element and updates on resize.

Drag the corner ↘

0 × 0

Installation

Usage

Element size, not viewport size. Use it for the decisions a media query cannot make: a card that switches layout because its column is narrow, a chart that needs pixel dimensions, a textarea that must re-measure when its container changes width.

import { useResizeObserver } from "@/hooks/use-resize-observer";

function Chart({ points }: { points: Point[] }) {
  const { ref, width, height } = useResizeObserver<HTMLDivElement>();

  return (
    <div ref={ref} className="h-64 w-full">
      {width > 0 ? <svg width={width} height={height}>{/* … */}</svg> : null}
    </div>
  );
}

ref is a callback ref, so the measurement starts as soon as the node attaches — including when the element mounts later or is swapped out.

Boxes

content-box (the default) excludes padding and border; border-box is the element's rendered size. Pick border-box when the number feeds back into a layout, so padding changes do not cause a measure-resize loop.

const { ref, width } = useResizeObserver<HTMLDivElement>({ box: "border-box" });

Options

OptionDescription
box"content-box" (default) or "border-box".
roundHow subpixel values are collapsed. Defaults to Math.round; pass Math.floor to avoid overflow, or (n) => n for exact values.
onResizeCalled on every observed change, for work that should not trigger a re-render.

Behavior

  • State updates are skipped when the rounded size did not change, so a resize that lands on the same integer does not re-render.
  • onResize is read from a ref and never re-subscribes the observer.
  • Before the first measurement — and during server rendering — width and height are 0. Branch on that rather than rendering a zero-sized canvas.