maslianok / react-resize-detector

A Cross-Browser, Event-based, Element Resize Detection for React
http://maslianok.github.io/react-resize-detector/
MIT License
1.25k stars 91 forks source link

ReactResizeDetector get's width and height of child component instead of targetRef's #111

Closed rapgodnpm closed 3 years ago

rapgodnpm commented 3 years ago

Code to reproduce

const component = () => {
        const containerRef = React.useRef(null)

        return (
           <div ref={containerRef}>
                <ReactResizeDetector handleWidth handleHeight targetRef={containerRef}>
                    {({ width, height }) => {
                      console.log(width, height)

                      return  (
                       <img width={width} height={height} src='whatever.png' />
                        )
                    }}
                 </ReactResizeDetector >
            </div>
        )
    }

In the console you will both the correct values of width and height (containerRef's width and height) and width and height. From what I've seen in the source code it's because of this line in getElement function from ResizeDetector:

if (this.targetRef && isDOMElement(this.targetRef.current)) return this.targetRef.current;

Since at first targetRef will be null (component is not yet mounted) the resize observer will not be attached to targetRef. It will be attached to this:

const currentElement = findDOMNode(this);

Since children prop is a function getElement will return findDOMNode(this). On update the resize observer is attached to targetRef but it does not disconnect from findDOMNode(this); thus observing both elements for changes and it some cases they may have different values. In my code, the is a React component that renders an image and the width and height returned from the ReactResizeDetector is 0. It would be good to not attach the resize observer to findDOMNode(this); if a targetRef is provided even though the targetRef.current value is not a dom element (or at least not yet).

maslianok commented 3 years ago

Yes, you're right. The library expects <div ref={containerRef}> to be inside the ReactResizeDetector. In this case, it will be mounted before the ReactResizeDetector. This should resolve the bug.

Another possible solution is to update to v6.0.0. In this version, we introduce hook support (example). The stable release will be published in a few days.

Let me know if you have any questions.