{"id":11900,"library":"react-use-measure","title":"React Hook to Measure Element Bounds","description":"`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.","status":"active","version":"2.1.7","language":"javascript","source_language":"en","source_url":"https://github.com/pmndrs/react-use-measure","tags":["javascript","react","use","measure","bounds","hooks","typescript"],"install":[{"cmd":"npm install react-use-measure","lang":"bash","label":"npm"},{"cmd":"yarn add react-use-measure","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-use-measure","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for all React hooks functionality.","package":"react","optional":false},{"reason":"Needed for DOM measurements within a React environment. It became an optional peer dependency in v2.1.3.","package":"react-dom","optional":true}],"imports":[{"note":"This is a default export, not a named export. Ensure you import it without curly braces.","wrong":"import { useMeasure } from 'react-use-measure'","symbol":"useMeasure","correct":"import useMeasure from 'react-use-measure'"},{"note":"Used to inject a polyfill for `ResizeObserver` if not natively available in the target environment or to provide a specific implementation via the `polyfill` option.","symbol":"ResizeObserver","correct":"import { ResizeObserver } from '@juggle/resize-observer'"},{"note":"When you need to assign multiple refs (e.g., `useMeasure`'s ref and your own `useRef`) to the same DOM element, you must use an external utility like `react-merge-refs` to combine them.","symbol":"mergeRefs","correct":"import { mergeRefs } from 'react-merge-refs'"}],"quickstart":{"code":"import useMeasure from 'react-use-measure';\nimport { useRef, useEffect } from 'react';\nimport { ResizeObserver } from '@juggle/resize-observer'; // Optional polyfill\n\nfunction App() {\n  const [ref, bounds] = useMeasure({\n    // Optional: inject a polyfill if your target environments don't support ResizeObserver\n    polyfill: typeof window !== 'undefined' && 'ResizeObserver' in window ? undefined : ResizeObserver,\n    debounce: 100, // Debounce updates for performance\n    scroll: true // React to scroll changes within parent elements\n  });\n\n  // Example of using the bounds in a side effect\n  useEffect(() => {\n    if (bounds.width > 0) {\n      console.log('Element dimensions:', bounds.width, 'x', bounds.height);\n    }\n  }, [bounds]);\n\n  return (\n    <div style={{ padding: '20px', border: '1px solid #ccc', marginBottom: '20px' }}>\n      <h1>ResizeObserver Hook Example</h1>\n      <p>Resize your browser window or interact with the measured div.</p>\n      <div\n        ref={ref}\n        style={{\n          width: '50%',\n          minHeight: '100px',\n          background: 'lightblue',\n          resize: 'both', // Allows manual resizing\n          overflow: 'auto',\n          margin: '20px auto',\n          padding: '10px'\n        }}\n      >\n        <p>This div is measured:</p>\n        <p>Width: {bounds.width}px</p>\n        <p>Height: {bounds.height}px</p>\n        <p>Top: {bounds.top}px, Left: {bounds.left}px</p>\n        <div style={{ height: '200px', width: '100%', background: 'lightcoral', marginTop: '10px' }}>\n          Scrollable content inside.\n          {Array.from({ length: 50 }).map((_, i) => <div key={i}>Item {i}</div>)}\n        </div>\n      </div>\n      <div style={{ height: '500px', background: '#eee' }}>\n        A larger container to enable page scrolling and demonstrate `scroll: true`.\n      </div>\n    </div>\n  );\n}\n\nexport default App;","lang":"typescript","description":"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."},"warnings":[{"fix":"Conditionally render UI based on `bounds.width > 0` or provide placeholder content during the initial render.","message":"The `bounds` object will initially contain zero values (`x: 0, y: 0, width: 0, height: 0, ...`) on the first render, as measurements are only possible after the element has been mounted to the DOM. Your UI should account for this initial state.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Install `@juggle/resize-observer` (or another polyfill) and inject it via the `polyfill` option: `useMeasure({ polyfill: ResizeObserver })`.","message":"`react-use-measure` relies on the `ResizeObserver` API. If your target environments (e.g., older browsers) do not support `ResizeObserver`, you will need to provide a polyfill.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use an external utility like `react-merge-refs` to combine multiple refs onto a single DOM element.","message":"`useMeasure` returns its own functional ref for unmount tracking. If you need to assign another ref (e.g., from `useRef`) to the same element, you cannot do so directly. Using both will cause one to overwrite the other.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Pass `{ scroll: true }` to the `useMeasure` hook options: `useMeasure({ scroll: true })`.","message":"By default, `react-use-measure` does not react to changes caused by scrolling in parent elements. To enable this behavior, you must explicitly set the `scroll` option to `true`.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Install `@juggle/resize-observer` and inject it into the `useMeasure` options: `import { ResizeObserver } from '@juggle/resize-observer'; useMeasure({ polyfill: ResizeObserver });`","cause":"The browser or runtime environment does not natively support the ResizeObserver API, and a polyfill has not been provided.","error":"ReferenceError: ResizeObserver is not defined"},{"fix":"Ensure you handle the initial state where `bounds` might not have meaningful values yet, for example, by checking `if (bounds.width > 0)` or providing default values.","cause":"Attempting to access `bounds.width` or other properties of the `bounds` object before the component has rendered and `useMeasure` has provided initial measurement values. `bounds` will be an empty object or have zero values initially.","error":"TypeError: Cannot read properties of undefined (reading 'width')"},{"fix":"Change the import statement from `import { useMeasure } from 'react-use-measure'` to `import useMeasure from 'react-use-measure'`.","cause":"Attempting to import `useMeasure` as a named export with curly braces, when it is a default export of the package.","error":"TypeError: (0 , react_use_measure__WEBPACK_IMPORTED_MODULE_2__.useMeasure) is not a function"}],"ecosystem":"npm"}