如果父级卸载,请不要卸载子级

时间:2018-04-20 12:41:15

标签: javascript reactjs window.open portal unmount

我有一个组件要在新的浏览器窗口中呈现,我大致使用这种技术:https://hackernoon.com/using-a-react-16-portal-to-do-something-cool-2a2d627b0202

这是它的简短摘录:

class MyWindowPortal extends React.PureComponent {
  constructor(props) {
    super(props);
    // STEP 1: create a container <div>
    this.containerEl = document.createElement('div');
    this.externalWindow = null;
  }
  
  render() {
    // STEP 2: append props.children to the container <div> that isn't mounted anywhere yet
    return ReactDOM.createPortal(this.props.children, this.containerEl);
  }

  componentDidMount() {
    // STEP 3: open a new browser window and store a reference to it
    this.externalWindow = window.open('', '', 'width=600,height=400,left=200,top=200');

    // STEP 4: append the container <div> (that has props.children appended to it) to the body of the new window
    this.externalWindow.document.body.appendChild(this.containerEl);
  }

  componentWillUnmount() {
    // STEP 5: This will fire when this.state.showWindowPortal in the parent component becomes false
    // So we tidy up by closing the window
    this.externalWindow.close();
  }
}

TL; DR:将反应门户附加到新窗口。

上述示例的完整工作代码集:https://codepen.io/davidgilbertson/pen/xPVMqp

这就像魅力一样,甚至可以在新窗口中更新组件。由于门户网站是打开新窗口的组件的子项,因此当我关闭父组件的页面时它也会关闭(即通常卸载)。

是否有可能保持新窗口打开并显示当前内容?它不需要再改变了,基本上冻结就好了(没有状态更新等等)。只需保留渲染的内容。

非常感谢任何帮助:)

1 个答案:

答案 0 :(得分:0)

关闭标签时,您不需要致电closeWindowPortal()。 在Codepen示例中,您可以从<App />

中删除它
window.addEventListener('beforeunload', () => {
  this.closeWindowPortal();
});