假设我正在构建一个带有react / redux& amp;的桌面应用程序。电子。所以我在电子中的index.html文件如下所示:
<!DOCTYPE html>
<html>
...
<body>
<div id="content"></div>
<script src="public/js/bundle.js"></script>
</body>
</html>
我最大的React容器(称为app.js)被加载到'id = content'div中。到目前为止这个工作正常,但现在我想知道如何在用户单击我的react应用程序中的按钮时打开一个新的文件对话框窗口(或任何新窗口)。
我找到了一些例子here&amp; here,但这两个示例仅解释了如何从主电子过程(渲染器或主要)加载文件对话框窗口。
但是,我希望用户使用我的React应用程序然后,一旦他或她点击一个按钮,我的应用程序应该告诉电子产生一个新窗口,当然,这个新窗口应该是某种程度上的一部分我的反应应用程序。
如果有人能在这里提供一个最简单的例子,我会非常感激,关于这些事情如何协同工作。
答案 0 :(得分:5)
要在新窗口中单击按钮来打开react组件并检测窗口何时关闭 ,因为关闭窗口时组件不会简单地调用componentWillUnmount
< / em>您的应用应该看起来像这样
App.js
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
// To keep track of the new window if opened or closed
isNewWindow: false,
};
}
render() {
return(
// onClose will be fired when the new window is closed
// everything inside NewWindowComponent is considered props.children and will be
// displayed in a new window
{(this.state.isNewWindow) &&
<NewWindowComponent
onClose={() => this.setState({ isNewWindow: false })>
<h2>This will display in a new window</h2>
</NewWindowComponent> }
<button
onClick={() => this.setState({ isNewWindow: true })}>
Open in new window</button>
)
}
}
NewWindowComponent.js
export default class NewWindowComponent extends Component {
// Create a container <div> for the window
private containerEl = document.createElement('div');
// This will keep a reference of the window
private externalWindow = null;
// When the component mounts, Open a new window
componentDidMount() {
// The second argument in window.open is optional and can be set to whichever
// value you want. You will notice the use of this value when we modify the main
// electron.js file
this.externalWindow = window.open('', 'NewWindowComponent ');
// Append the container div and register the event that will get fired when the
// window is closed
if (this.externalWindow)
{
this.externalWindow.document.body.appendChild(this.containerEl);
this.externalWindow.onunload = () => this.props.onClose();
}
}
render() {
return ReactDOM.createPortal(this.props.children, this.containerEl);
}
}
electron-main.js ,或者您的主电子文件被命名为
...
function createWindow() {
mainWindow = new BrowserWindow({
...
// You need to activate `nativeWindowOpen`
webPreferences: { nativeWindowOpen: true },
});
...
mainWindow.webContents.on('new-window',
(event, url, frameName, disposition, options, additionalFeatures) =>
{
// This is the name we chose for our window. You can have multiple names for
// multiple windows and each have their options
if (frameName === 'NewWindowComponent ') {
event.preventDefault();
Object.assign(options, {
// This will prevent interactions with the mainWindow
parent: mainWindow,
width: 300,
height: 300,
// You can also set `left` and `top` positions
});
event.newGuest = new BrowserWindow(options);
}
});
...
}
...
答案 1 :(得分:2)
反应16中的“createPortal”api将对您有所帮助。
首先,我们假设我们有一个这样的组件:
<SubWindow>
<h1>bar</h1>
</SubWindow>
然后在其生命周期方法中打开(或关闭)一个窗口,如下所示:
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;
}
}
注意:您必须在主窗口中设置webPreferences:{nativeWindowOpen:true},以确保“window.open”返回本机Window对象。请访问https://electronjs.org/docs/api/window-open了解详情。