diff --git a/packages/grafana-ui/src/components/Portal/Portal.tsx b/packages/grafana-ui/src/components/Portal/Portal.tsx index e3bb95f84ef..b2705ed006c 100644 --- a/packages/grafana-ui/src/components/Portal/Portal.tsx +++ b/packages/grafana-ui/src/components/Portal/Portal.tsx @@ -1,4 +1,4 @@ -import React, { PropsWithChildren, useEffect, useState } from 'react'; +import React, { PropsWithChildren, useLayoutEffect, useRef } from 'react'; import ReactDOM from 'react-dom'; import { useTheme2 } from '../../themes'; @@ -9,25 +9,30 @@ interface Props { } export function Portal(props: PropsWithChildren) { - const { children, className, root = document.body, forwardedRef } = props; + const { children, className, root: portalRoot = document.body, forwardedRef } = props; const theme = useTheme2(); - const [node] = useState(document.createElement('div')); - const portalRoot = root; - - if (className) { - node.classList.add(className); + const node = useRef(null); + if (!node.current) { + node.current = document.createElement('div'); + if (className) { + node.current.className = className; + } + node.current.style.position = 'relative'; + node.current.style.zIndex = `${theme.zIndex.portal}`; } - node.style.position = 'relative'; - node.style.zIndex = `${theme.zIndex.portal}`; - useEffect(() => { - portalRoot.appendChild(node); + useLayoutEffect(() => { + if (node.current) { + portalRoot.appendChild(node.current); + } return () => { - portalRoot.removeChild(node); + if (node.current) { + portalRoot.removeChild(node.current); + } }; - }, [node, portalRoot]); + }, [portalRoot]); - return ReactDOM.createPortal(
{children}
, node); + return ReactDOM.createPortal(
{children}
, node.current); } export const RefForwardingPortal = React.forwardRef((props, ref) => {