【问题标题】:Rendering an iFrame within a React Portal在 React Portal 中渲染 iFrame
【发布时间】:2023-09-12 14:10:01
【问题描述】:

我正在创建一个Logger 服务来跟踪我的应用程序中的事件。为了使 Logger 服务通用,我使用 React 的 Portal 来捕获在我的应用程序中触发的事件。我的应用程序的基本思想是:

<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 组件而没有包裹它的 Portal 时,iframe.contentDocument 会按预期记录。

ReactDOM.render(<Frame />,rootElement)

但是当我渲染封装在 Portal 中的 Frame 组件时,iFrame.contentDocument 的值是 null

ReactDOM.render(
  <LoggerPortal>
    <Frame />
  </LoggerPortal>,
  rootElement
);

这是一个codesandbox,它有一个描述我的问题的应用程序。有人在使用门户网站和 iFrame 时遇到过这个问题吗?我在这里遗漏了什么明显的东西吗?

【问题讨论】:

    标签: javascript reactjs iframe react-hooks react-portal


    【解决方案1】:

    棘手的问题!

    useRef 在您进行更改以使 React 添加或删除 DOM 节点时不会导致重新渲染。在您的情况下,将iframe 附加到您的&lt;Portal&gt;props.children,因此您的控制台将返回null。您必须改用回调引用:useCallback

    因此,要获取 iframe 的引用,您可以尝试:

      let refiFrame =  useCallback(node => {
        refiFrame = node
      });
    

    这是您的代码框的修改版:https://codesandbox.io/s/portal-iframe-dmmnx

    【讨论】: