useElementSize()
This hook helps you to dynamically recover the width and the height of an HTML element. Dimensions are updated on load, on mount/un-mount, when resizing the window and when the ref changes.
The Hook
1import { useCallback, useState } from 'react'23import { useEventListener, useIsomorphicLayoutEffect } from 'usehooks-ts'45interface Size {6 width: number7 height: number8}910function useElementSize<T extends HTMLElement = HTMLDivElement>(): [11 (node: T | null) => void,12 Size,13] {14 // Mutable values like 'ref.current' aren't valid dependencies15 // because mutating them doesn't re-render the component.16 // Instead, we use a state as a ref to be reactive.17 const [ref, setRef] = useState<T | null>(null)18 const [size, setSize] = useState<Size>({19 width: 0,20 height: 0,21 })2223 // Prevent too many rendering using useCallback24 const handleSize = useCallback(() => {25 setSize({26 width: ref?.offsetWidth || 0,27 height: ref?.offsetHeight || 0,28 })2930 // eslint-disable-next-line react-hooks/exhaustive-deps31 }, [ref?.offsetHeight, ref?.offsetWidth])3233 useEventListener('resize', handleSize)3435 useIsomorphicLayoutEffect(() => {36 handleSize()37 // eslint-disable-next-line react-hooks/exhaustive-deps38 }, [ref?.offsetHeight, ref?.offsetWidth])3940 return [setRef, size]41}4243export default useElementSize
Usage
1import { useState } from 'react'23import { useElementSize } from 'usehooks-ts'45export default function Component() {6 const [isVisible, setVisible] = useState(true)7 const [squareRef, { width, height }] = useElementSize()89 const toggleVisibility = () => setVisible(x => !x)1011 return (12 <>13 <p>{`The square width is ${width}px and height ${height}px`}</p>14 <p>Try, resize your window and-or click on the button.</p>1516 <button onClick={toggleVisibility}>17 {isVisible ? 'Hide' : 'Show'} square18 </button>1920 {isVisible && (21 <div22 ref={squareRef}23 style={{24 width: '50%',25 paddingTop: '50%',26 backgroundColor: 'aquamarine',27 margin: 'auto',28 }}29 />30 )}31 </>32 )33}
See a way to make this page better?
Edit there »