useMeasure
Real-time element dimension tracking using ResizeObserver.
300px
Resize Me
W: 0pxH: 0px
0 × 0
Usage
import { useMeasure } from 'usehooks-ts'
export default function Component() {
const [ref, { width, height }] = useMeasure()
return (
<div ref={ref}>
I am {width}px wide and {height}px tall
</div>
)
}API
const [ref, rect] = useMeasure<E>()Type Parameters
| Parameter | Default | Description |
|---|---|---|
E | HTMLElement | The type of the HTML element to measure |
Return Values
| Name | Type | Description |
|---|---|---|
ref | RefObject<E> | React ref to attach to the target element |
rect | MeasureResult | Object containing dimension properties |
MeasureResult Interface
interface MeasureResult {
width: number
height: number
top: number
left: number
bottom: number
right: number
x: number
y: number
}Hook
import { useState, useRef, useLayoutEffect, useEffect } from 'react'
export interface MeasureResult {
width: number
height: number
top: number
left: number
bottom: number
right: number
x: number
y: number
}
const defaultState: MeasureResult = {
x: 0,
y: 0,
width: 0,
height: 0,
top: 0,
left: 0,
bottom: 0,
right: 0,
}
const isBrowser = typeof window !== 'undefined'
const useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : useEffect
export function useMeasure<E extends HTMLElement = HTMLElement>() {
const ref = useRef<E>(null)
const [rect, setRect] = useState<MeasureResult>(defaultState)
useIsomorphicLayoutEffect(() => {
if (!ref.current) return
const observer = new ResizeObserver(([entry]) => {
if (entry) {
setRect(entry.contentRect)
}
})
observer.observe(ref.current)
return () => {
observer.disconnect()
}
}, [])
return [ref, rect] as const
}