在某些步骤中,我向用户显示iframe.
当用户在步骤之间导航时,它总是卸载并重新安装iframe,这会导致两个问题:
>它从源代码重新加载iframe,这使它跳转.
>因为它是一个iframe,我无法控制其内部状态,并且它失去了步骤之间的状态.因此,如果用户对iframe有一些输入,则在移动到下一步时输入会丢失.
有没有办法将iframe实例保留在某个全局存储中,并且只在必要时将其挂载到DOM?
任何其他想法如何解决这个问题?
谢谢.
解决方法
Is there any way to keep the iframe instance in some global store and
only mount it to the DOM when necessary ?
是的,你可以,但如果你甚至从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以保持其状态并防止重新加载.