Go Pro Sign Up Login
0 days 0 hrs 0 min 0 sec

Summer Sale

50% off Level Up Pro until you unsubscribe.
Get access to ALL 128 courses on Level Up Tutorials

This is your last chance to get Level Up Pro for $145/year.

or Learn More
Moon Moon

Buy Now and unlock this series







yours forever

Become a Pro and unlock everything




per month

Animating Height Auto


import { useRef, useState, useEffect } from 'react'
import ResizeObserver from 'resize-observer-polyfill'

export default function useMeasure() {
  const ref = useRef()
  const [bounds, set] = useState({ left: 0, top: 0, width: 0, height: 0 })
  const [ro] = useState(() => new ResizeObserver(([entry]) => set(entry.contentRect)))
  useEffect(() => (ro.observe(ref.current), ro.disconnect), [])
  return [{ ref }, bounds]


Become a pro to download code and videos



over 1 year ago [edited]

If anyone is looking for a more succinct hook for height measurement, I found this one:

export function useHeight({ on = true /* no value means on */ } = {} as any) { const ref = useRef(); const [height, set] = useState(0); const heightRef = useRef(height); const [ro] = useState( () => new ResizeObserver(packet => { if (ref.current && heightRef.current !== ref.current.offsetHeight) { heightRef.current = ref.current.offsetHeight; set(ref.current.offsetHeight); } }) ); useLayoutEffect(() => { if (on && ref.current) { set(ref.current.offsetHeight); ro.observe(ref.current, {}); } return () => ro.disconnect(); }, [on, ref.current]); return [ref, height as any]; } At CSS tricks: https://css-tricks.com/making-sense-of-react-spring/

User avatar


over 1 year ago

Yep, just as for Josh, my app would throw an "illegal invocation" error. For unmount ro.unobserve(ref.current) function it'd still crash out on me bc the ref.current on route change would be undefined, but just using ro.disconnect() worked well for my case.

User avatar


almost 3 years ago

Thanks Josh, was so happy to read ur comment :) I was struggling aswell.

Great series Scott :)

User avatar


almost 3 years ago

In love with this series!! It‘s really helping out on an animation heavy project right now.

Just wanted to point out that I had some issues with my app crashing when routing away from a component that utilized the “useMeasure“ hook. And after some digging, I found the observer was still looking for the unmounted bounded ref.

Changing the useEffect to this did the trick:

useEffect(() => { ro.observe(ref.current); return () => ro.unobserve(ref.current); }, []);

Want to join the conversation?

Become a Pro member today!