react-measure icon indicating copy to clipboard operation
react-measure copied to clipboard

How to use `ref` on custom element?

Open quintesse opened this issue 6 years ago • 5 comments

First, sorry for using the issue tracker for a question, but I didn't see any mention of a mailing list or forum!

So my question is how to use <Measure> with a custom element, like for example a semantic-ui control? I'm trying to do this:

<Measure ....>
  {({measureRef}) => (<Card ref={measureRef} ....> .... </Card>)}
</Measure>

but that results in "TypeError: Failed to execute 'observe' on 'ResizeObserver': parameter 1 is not of type 'Element'".

I can add a <div> around it and put the ref on that but that results in the bounds not being exactly correct (they tend to be quite a bit bigger than the actual element I'm trying to measure).

Any ideas?

quintesse avatar Jul 24 '18 02:07 quintesse

You need to pass ref to the element rendered by the custom component, for example:

const Card = ({ innerRef, children }) => <div ref={innerRef}>{children}</div>

more on that here

adekbadek avatar Jul 30 '18 08:07 adekbadek

I probably didn't explain this well enough, but what I wanted to say was:

So my question is how to use <Measure> with a custom element not made by me and therefore unable to change the way it works, like for example a semantic-ui control?

So there's no way for me to pass an innerRef.

quintesse avatar Jul 30 '18 08:07 quintesse

I guess if the library you're using does not provide a way of passing a ref to then rendered element, then you're out of luck :/

But maybe I'm wrong and there is some (maybe hacky) way of accessing the ref?

adekbadek avatar Jul 30 '18 12:07 adekbadek

Well yes, there is, I'm currently using ReactDOM.findDOMNode() to get the underlying DOM element and just ask for it's bounds directly using plain DOM + JS. It means not using >Measure> anymore, I made my own <DOMRef> component that has a callback that gives me the DOM node. I know they advise against using ReactDOM.findDOMNode() but I don't see any other way in my case.

quintesse avatar Jul 30 '18 16:07 quintesse

You can just wrap the custom element with a div. In most cases, the dimensions of the wrapper should be the same as the ones of the inner element:

<Measure ...>
  {({measureRef}) => <div ref={measureRef}><Card ...> ... </Card></div>}
</Measure>

cloudlena avatar Oct 17 '18 12:10 cloudlena