Minimal Example: Opening a window in electron from

2020-07-27 02:08发布

问题:

Say I am building a desktop application with react/redux & electron. So my index.html file in electron looks like this:

<!DOCTYPE html>
<html>
 ...
  <body>

    <div id="content"></div>

  <script src="public/js/bundle.js"></script>
  </body>
</html>

My biggest React container (call it app.js) is loaded into the 'id=content' div. This works fine so far, but now I am wondering how to open a new file dialog window (or any new window for that matter) when the user clicks a button in my react application.

I found some examples here & here, but both examples only explain how to load the file dialog window from the main electron processes (in renderer or main).

However, I want the user to engage with my React Application and then, once he or she clicks a button, my app should then tell electron to spawn a new window, and this new window should, of course, somehow be part of my react application.

I would really appreciate it if someone could provide a minimal example here, on how these to things work together.

回答1:

The "createPortal" api in react 16 will help you.

First let's say we have a component like this:

<SubWindow>
  <h1>bar</h1>
</SubWindow>

Then open(or close) a window in its lifecycle methods like this:

export class SubWindow extends React.Component {
  nativeWindowObject: null;

  componentWillMount() {
    this.nativeWindowObject = window.open('');
  }
  render() {
    return this.nativeWindowObject ? ReactDOM.createPortal(this.props.children, this.nativeWindowObject.document.body) : null;
  }
}

Notice: You MUST set webPreferences:{nativeWindowOpen: true} in your main window to make sure "window.open" returns a native Window object. Visit https://electronjs.org/docs/api/window-open for more infomation.



回答2:

On clicking the button handleNewWindow is called. Make the nodeIntegration to true or preload js.

const handleNewWindow =()=> {
    const remote=require('electron').remote;
    const BrowserWindow=remote.BrowserWindow;
    const win = new BrowserWindow({
      height: 600,
      width: 800,
      frame:false,
      webPreferences: {
        nodeIntegration: true,
    }
    });
    win.loadURL(`file://${__dirname}/app.html#/login`);


  }

And on the router file

<Route path="/login" component={Login} />

By using this code we can open the reactjs file and route to login. The app.html is main file which is loaded in main.dev.js in electron-react-boilerplate code. The hashing is simplest method to open the reactjs file. As the loadURL in electron only loads urls and htmls files we can't open js files.