React forwardRef does not seem to work with bootstrap Overlay
Asked Answered
B

0

3

According to React-Bootstrap Overlays docs, the target of the overlay should be the element the overlay is positioned in relation to which works beautifully if the target is inline. such as the Example 1 below.

If however the referenced dom item is contained inside of another component as illustrated with Example 2 then the reference is not setup correctly and the popover does not get positioned correctly.

I was not forwarding the ref at first, and believed that to be my problem, but even after fixing that according to the React.forwardRef docs, the ref is still not working correctly.

Possible Solution: I could put my target incline instead of another component but that removes the purpose of being able to use components in React.

I am probably missing a small step somewhere in this setup, I just don't know where.

I did find an alternative working solution as I was writing this out and looking for duplicates. As seen in Simon Arsenault's Answer by wrapping the component in a dom element, I could use that dom element as the ref as seen in Example 3

I would still like to know why the forwardRef does not seem to work though.

Example 1: Working

...
export default (props) => {
  const [show, setShow] = useState(false)
  const target = useRef(null)
  ...
  return (
    <div>
      <p ref={target} >Click Me</p>
      <Overlay show={show} target={target.current} >
        <Popover id='123'>
          ...
        </Popover>
      </Overlay>
    </div>
  )
}

Example 2: Not Working

...
export default (props) => {
  const [show, setShow] = useState(false)
  const target = useRef(null)
  ...
  return (
    <div>
      <LinkIcon ref={target} />
      <Overlay show={show} target={target.current} >
        <Popover id='123'>
          ...
        </Popover>
      </Overlay>
    </div>
  )
}
...
const LinkIcon = React.forwardRef((props, ref) => {
  ...
  return (
    <div ref={ref}>
      ...
    </div>
  )
})

Example 3: Working

...
export default (props) => {
  const [show, setShow] = useState(false)
  const target = useRef(null)
  ...
  return (
    <div>
      <div ref={target}><LinkIcon /></div>
      <Overlay show={show} target={target.current} >
        <Popover id='123'>
          ...
        </Popover>
      </Overlay>
    </div>
  )
}
...
const LinkIcon = React.forwardRef((props, ref) => {
  ...
  return (
    <div ref={ref}>
      ...
    </div>
  )
})

P.S.: Yes, I know this is not a fully working example because I do not use Overlay's show property, but that is working correctly and left out of this code snippet for brevity.

Buhl answered 26/3, 2020 at 19:49 Comment(1)
Don't forget to add your passthrough createRef() via <LinkIcon ref={ref} per (the docs)[reactjs.org/docs/forwarding-refs.html]Vandenberg

© 2022 - 2024 — McMap. All rights reserved.