有没有办法将 iframe 实例保存在某个全局存储中,并且
仅在必要时将其挂载到 DOM 上?
是的,你可以,但是如果你甚至从 DOM 中删除一个 iframe 并稍后重新附加它,它仍然会被重新加载,所以这样问题实际上与 React 的组件树几乎没有关系。您真正需要的是隐藏您的 iframe 并稍后再次显示。
你当然可以像这样在 React 中隐藏和显示 iframe:
{ <iframe src="..." style={{display: this.state.showing ? "block" : "none"}} /> }
在这种情况下,您需要在 没有 被卸载的某个地方渲染 iframe。您可以使用树中更下方的组件向上通信以显示/隐藏 iframe。
但是,如果您真的希望能够从组件树中的 不同 位置隐藏/显示 iframe,这些位置将被安装和卸载,您可以,但它会变得相当棘手,而不是React 的典型用例。
您需要自己创建 DOM iframe 并将其附加到 React 组件树之外的 DOM 中(这通常是 React 中的反模式)。然后你可以使用代理组件在挂载和卸载时显示/隐藏这个 DOM 元素。
下面是一个示例,它将 iframe 附加到 document.body 并在安装组件时显示它,并在卸载组件时隐藏它:
class WebView extends React.Component {
static views = {};
componentDidMount() {
if (!WebView.views[this.props.url]) {
WebView.views[this.props.url] = this.createWebView(this.props.url);
}
WebView.views[this.props.url].style.display = "block";
}
componentWillUnmount() {
WebView.views[this.props.url].style.display = "none";
}
createWebView(url) {
let view = document.createElement("iframe");
view.src = this.props.url;
document.body.appendChild(view);
return view;
}
render() {
return null;
}
}
Here it is working on CodePen:请注意,当您隐藏(卸载)然后显示(安装)WebView 时,iframe 状态(例如搜索输入)保持不变。
您还需要调整 iframe 的位置和大小,以正确显示在您的布局中。我没有展示这个,因为它一般很难解决。
请注意,此解决方案类似于"portal" pattern。这里的区别是永远不要卸载 iframe 以保持其状态并防止重新加载。