What is react-use-measure?
The react-use-measure package is a React hook that allows you to measure the size and position of a DOM element. It provides a simple and efficient way to get the dimensions and position of an element, which can be useful for various UI-related tasks such as responsive design, animations, and more.
What are react-use-measure's main functionalities?
Basic Measurement
This feature allows you to measure the dimensions and position of a DOM element. The `useMeasure` hook returns a ref to attach to the element you want to measure and an object containing the measurements.
import React from 'react';
import { useMeasure } from 'react-use-measure';
const Example = () => {
const [ref, bounds] = useMeasure();
return (
<div>
<div ref={ref} style={{ width: '50%', height: '100px', background: 'lightblue' }}>
Measure me!
</div>
<pre>{JSON.stringify(bounds, null, 2)}</pre>
</div>
);
};
export default Example;
Responsive Measurement
This feature demonstrates how the `useMeasure` hook can be used to create responsive components that adapt to changes in their size and position. The measurements update automatically when the window is resized.
import React from 'react';
import { useMeasure } from 'react-use-measure';
const ResponsiveComponent = () => {
const [ref, bounds] = useMeasure();
return (
<div>
<div ref={ref} style={{ width: '100%', height: '200px', background: 'lightcoral' }}>
Resize the window to see changes
</div>
<pre>{JSON.stringify(bounds, null, 2)}</pre>
</div>
);
};
export default ResponsiveComponent;
Conditional Rendering Based on Measurements
This feature shows how you can use the measurements obtained from `useMeasure` to conditionally render elements based on the size of the measured element.
import React from 'react';
import { useMeasure } from 'react-use-measure';
const ConditionalRendering = () => {
const [ref, bounds] = useMeasure();
return (
<div>
<div ref={ref} style={{ width: '100%', height: '150px', background: 'lightgreen' }}>
Conditional Rendering
</div>
{bounds.width > 300 && <div>Width is greater than 300px</div>}
{bounds.height > 100 && <div>Height is greater than 100px</div>}
</div>
);
};
export default ConditionalRendering;
Other packages similar to react-use-measure
react-measure
react-measure is a similar package that provides a higher-order component (HOC) and a render prop component for measuring the size and position of DOM elements. It offers more flexibility in terms of how you can use it (HOC, render prop, or hook), but it may be slightly more complex to set up compared to react-use-measure.
react-resize-detector
react-resize-detector is another package that provides a way to detect changes in the size of a DOM element. It offers a hook, a render prop component, and a HOC for flexibility. It focuses more on detecting resize events rather than providing detailed measurements, making it simpler but less feature-rich compared to react-use-measure.
resize-observer-polyfill
resize-observer-polyfill is a polyfill for the ResizeObserver API, which allows you to observe changes to the size of an element. While not specifically a React package, it can be used in React applications to achieve similar functionality. It provides a lower-level API compared to react-use-measure, requiring more manual setup.
yarn add react-use-measure
This small tool will measure the boundaries (for instance width, height, top, left) of a view you reference. It is reactive and responds to changes in size, window-scroll and nested-area-scroll.
Why do we need this hook?
Because there is no simple way to just get relative view coordinates. Yes, there is getBoundingClientRect, but it does not work when your content sits inside scroll areas whose offsets are simply neglected (as well as page scroll). Worse, mouse coordinates are relative to the viewport (the visible rect that contains the page). There is no easy way, for instance, to know that the mouse hovers over the upper/left corner of an element. This hook solves it for you.
You can try a live demo here: https://codesandbox.io/s/musing-kare-4fblz
Usage
import useMeasure from 'react-use-measure'
function App() {
const [ref, bounds] = useMeasure()
return <div ref={ref} />
}
Api
interface RectReadOnly {
readonly x: number
readonly y: number
readonly width: number
readonly height: number
readonly top: number
readonly right: number
readonly bottom: number
readonly left: number
}
type Options = {
debounce?: number | { scroll: number; resize: number }
scroll?: boolean
polyfill?: { new (cb: ResizeObserverCallback): ResizeObserver }
offsetSize?: boolean
}
useMeasure(
options: Options = { debounce: 0, scroll: false }
): [React.MutableRefObject<HTMLElement | SVGElement>, RectReadOnly]
⚠️ Notes
Resize-observer polyfills
This lib relies on resize-observers. If you need a polyfill you can either polute the window
object or inject it cleanly using the config options. We recommend @juggle/resize-observer.
import { ResizeObserver } from '@juggle/resize-observer'
function App() {
const [ref, bounds] = useMeasure({ polyfill: ResizeObserver })
Multiple refs
useMeasure currently returns its own ref. We do this because we are using functional refs for unmount tracking. If you need to have a ref of your own on the same element, use react-merge-refs.