Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useMeasure #124

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Conversation

drbarzaga
Copy link
Contributor

This hook provides a convenient and efficient way to monitor and respond to changes in the size of a React component.

Addressed in this PR:

  • Add the useMeasure hook.
  • Add example of usage.

Demo

demo.mp4

Copy link
Member

@dlcastillop dlcastillop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing implementation, Dayan!

Here are a few suggestions for improvement:

  • Remove both examples: while they’re great, I prefer the examples to be real-world use cases, not just simple demonstrations. No need to feel obligated to include one.
  • For the hook, I suggest using useSyncExternalStore instead of useEffect for a more robust implementation. Here's the documentation and an example of your hook using useSyncExternalStore. Make sure to test it, though.
import { useRef, useSyncExternalStore } from 'react'

type Size = {
    width: number
    height: number
}

export const useMeasure = () => {
    const elementRef = useRef<HTMLElement | null>(null)

    const subscribe = (callback: () => void) => {
        const observer = new ResizeObserver(() => {
            callback()
        })

        if (elementRef.current) {
            observer.observe(elementRef.current)
        }

        return () => {
            if (elementRef.current) {
                observer.unobserve(elementRef.current)
            }
        }
    }

    const getSnapshot = (): Size => {
        if (!elementRef.current) {
            return { width: 0, height: 0 }
        }
        const { width, height } = elementRef.current.getBoundingClientRect()
        return { width, height }
    }

    const size = useSyncExternalStore(subscribe, getSnapshot)

    return [elementRef, size] as const
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants