2

I have a component that I want to render in a new browser window and I'm using roughly this technique: https://hackernoon.com/using-a-react-16-portal-to-do-something-cool-2a2d627b0202

This is a short extract of it:

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: appending a react portal to the new window.

Complete working codepen for the above example: https://codepen.io/davidgilbertson/pen/xPVMqp

This works like a charm and even updates the component in the new window. As the portal is a child of the component opening the new window, it also closes when I close the parent component's page (i.e. unmounting in general).

Is there any possibility to keep the new window open and the current content in it? It does not need to change anymore, basically freezing it in place would be fine (no state updates and whatnot). Just keep what was rendered.

Any help is highly appreciated :)

  • can you change the `` from the Codepen example? – Doron Brikman Apr 20 '18 at 13:24
  • I have full control over all components, if that's what you are asking. A solution as close as possible to the two components directly involved would be nice, though, without going all the way up to root. – Crotaphytus Apr 20 '18 at 13:54

1 Answers1

0

You just don't need to call closeWindowPortal() when you close the tab. In the Codepen example you can remove this from <App />:

window.addEventListener('beforeunload', () => {
  this.closeWindowPortal();
});
Doron Brikman
  • 2,444
  • 1
  • 16
  • 17
  • That is the obvious solution for the codepen, that's true. I didn't have that one in mind, when posting the code to illustrate, what I would like to have. The thing is, that I don't have such a method in my own . Its seems like I have to actively freeze the thing or something. I'm using react-router, btw, if that helps. – Crotaphytus Apr 23 '18 at 07:00