Is there a way to get ref
from a React 16 portal. I tried the following approach but it doesn't seem to work:
const Tooltip = props => (
ReactDOM.createPortal(
<div>{props.children}</div>,
// A DOM element
document.body
)
);
class Info extends React.Component {
render() {
return (
<Tooltip
ref={ el => this.tooltip = el }
>
My content
</Tooltip>
);
}
componentDidMount() {
console.log(this.tooltip); // undefined
}
}
I need the ref
in order to dynamically calculate the element final position!
https://codepen.io/anon/pen/QqmBpB
ReactDOM.createPortal
returns a ReactPortal instance, which is a valid ReactNode but not a valid DOM element. At the same time createPortal
will honour the component context. So I moved the function call to be inside the render method and it solved the issue.
class Info extends React.Component {
render() {
// I moved the portal creation to be here
return ReactDOM.createPortal(
// A valid DOM node!!
<div ref={ el => this.tooltip = el }>{props.children}</div>,
// A DOM element
document.body
);
}
componentDidMount() {
console.log(this.tooltip); // HTMLDivElement
}
}
If you want to do it with hooks, you can also do
import { createPortal } from 'react-dom'
import React, { useRef } from 'react'
const Portal = ({ children }) => {
const portal = useRef(document.createElement('div'))
return createPortal(children, portal.current)
}
Also, in your exact example, you would need to use forwardRef
since you can't pass refs
to children without it.
const Tooltip = forwardRef((props, ref) => (
createPortal(
<div ref={ref}>{props.children}</div>,
// A DOM element
document.body
)
));
const Info = () => {
const ref = useRef()
return (
<Tooltip ref={ref}>
My content
</Tooltip>
)
}
This last bit is not tested, but I'm pretty sure it'll work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With