Skip to content

The useSize() demo for resize-observer doesn't capture element's initial size #165

@jdthorpe

Description

@jdthorpe

Describe the bug
The useSize() function in the demo for @react-hook/resize-observer uses the anti-pattern of depending on the ref object provided by React.useRef() in the dependency list of React.useLayoutEffect(). This has the effect of not setting an initial value for the size on the first rendering. This matters because elements that don't get re-rendered never get a sized.

To Reproduce
Use the size

Expected behavior
Get a size for elements on the first time they are rendered.

Additional context
Depending on the node itself via useState instead of the ref (which is never updated and therefor never calls) is the usual work around

export function useSize(): {
    ref: (node: HTMLDivElement | null) => void
    size: DOMRect | undefined
} {
    const [size, setSize] = useState<DOMRect | undefined>()
    const [node, ref] = useState<HTMLElement | null>(null)

    useLayoutEffect(() => {
        node !== null && setSize(node.getBoundingClientRect())
    }, [node])

    // Where the magic happens
    useResizeObserver(node, (entry) => {
        setSize(entry.contentRect)
    })

    return { ref, size } // this is also a little wierd since ref isn't a ref object but a setter function, but works if using it in the context of <div ref={ref}>
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions