iamyojimbo
iamyojimbo

Reputation: 4689

React: How to use refs in a function component that I have no control over (i.e. from a library)

I can't believe I couldn't find an answer on this so please point me in the right direction if I am wrong.


I am trying to do something simple:

There's a function component from a library that I include.

I need to get a ref to it.

Crucially, React says this:

Ref forwarding lets components opt into exposing any child component’s ref as their own.

Unfortunately, this library component has not opted in using forwardRef.

What is the correct approach to get a ref to this element?

The 3rd party library component in question looks like so (simplified):

function OutboundLink(props) {
  return (
    <a {...props}
        ...
    />
  )
}

My component looks like so:

function MyComp(props) {
  const ref = useRef(null)
  return (
    <OutboundLink ref={ref} {...props} >
      {children}
    </OutboundLink>
  )
}

but I am greeted with the errors about not being able to pass refs to a function component. Normally I would wrap in forwardRef, but can't in this case since I can't modify the library's code directly.

I did see this and this but didn't think either applied to me.

Any ideas?

Upvotes: 5

Views: 1377

Answers (1)

Alex Wayne
Alex Wayne

Reputation: 187074

You can't directly. There's no hook to let you in if the component wasn't written that way.

I think your best bet would be to wrap the component, capture a ref, and then drill into its children with DOM methods.

const wrapperRef = useRef(null)
const innerRef = useRef(null)

useEffect(() => {
  if (wrapperRef.current) {
    innerRef.current = wrapperRef.current.querySelector('a')
    // innerRef.current is now the first <a> tag inside <OutboundLink>
  }
})

return <div>
  <div ref={wrapperRef}>
    <OutboundLink {...props}>
      {children}
    </OutboundLink>
  </div>
</div>

Codepen example (view the console)

But really, this is a bit of a hack. You should use a component that handles this better. Look into how hard it would be to write this component yourself from scratch. It may be trivial, and worth it.

Upvotes: 6

Related Questions