4

我正在创建一个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现在,当我在没有门户包裹的情况下在上面渲染这个组件时,iframe.contentDocument日志符合预期。

ReactDOM.render(<Frame />,rootElement)

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

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

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

4

1 回答 1

2

棘手的问题!

useRef当您进行更改以使 React 添加或删除 DOM 节点时,不会导致重新渲染。在您的情况下,将 an 附加iframe到您<Portal>的 'sprops.children上,因此您的控制台正在返回null. 您必须改用回调 ref:useCallback

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

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

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

于 2019-07-30T02:32:59.207 回答