i正在创建一个Logger
服务,该服务将在我的应用程序中跟踪事件。为了使Logger
Service通用,我使用React的门户来捕获应用程序中射出的事件。我的应用程序的基本思想是:
<LoggerPortal>
<App>
</LoggerPortal>
这对我的用例效果很好,直到我在应用程序中使用了iFrame
。
考虑一个非常简单的组件,该组件呈现iframe:
const Frame = props => {
const refiFrame = useRef(null);
useEffect(() => {
console.log(refiFrame.current.contentDocument);
}, []);
return (
<>
<iframe id="i-framed-you" title="original-iframe-title" ref={refiFrame} />
</>
);
};
现在,当我将此Frame
组件渲染到上面而没有包裹的门户网站时,iframe.contentDocument
按预期登录。
ReactDOM.render(<Frame />,rootElement)
但是,当我渲染包裹在门户中的Frame
组件时,iFrame.contentDocument
的值为 null 。
ReactDOM.render(
<LoggerPortal>
<Frame />
</LoggerPortal>,
rootElement
);
这是一个代码框,它具有描述我问题的应用程序。使用门户和iframe时,有人看过这个问题吗?我在这里缺少明显的东西吗?
棘手的问题!
当您进行更改以使React添加或删除DOM节点时,useRef
不会引起重新渲染。在您的情况下,将iframe
附加到<Portal>
的props.children
上,因此您的控制台正在返回null
。您必须使用回调参考:useCallback
所以,要将裁判置于您的iframe,您可以尝试:
let refiFrame = useCallback(node => {
refiFrame = node
});
这是您的CODESANDBOX的工作修改版本:https://codesandbox.io/s/portal-iframe-dmmnx