在渲染函数中使用 window.require('electron') 会导致整个屏幕变黑。电子、反应、Material UI

Using window.require('electron') in a render function causes the whole screen to go blank. Electron, React, Material UI

我正在尝试使用 Electron、React.js 和 Material UI 构建程序。我可以打开应用程序,并按预期显示屏幕。但是,当我尝试在渲染组件中使用 ipcRender 时,整个屏幕变为空白。我可以验证这是导致问题的代码行,因为只需将其注释掉即可恢复所有内容。我需要此功能来制作自定义应用栏。

我曾尝试从渲染函数的 require 语句中删除 window.,但那会停止反应并引发错误。我也试过设置 nodeIntegration: true 但这没有任何改变。

这是主文件。

// Modules to control application life and create native browser window
const {app, BrowserWindow, Tray, nativeImage, ipcMain} = require('electron')
const path = require('path')
const Store = require('electron-store')

let tray, window

function createWindow () {
  // Create the browser window.
  window = new BrowserWindow({
    width: 800,
    height: 600,
    show: true,
    frame: true,
    title: 'Nozdive Program',
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: false
    }
  })

  window.on('closed', () => window = null)

  // and load the index.html of the app.
  window.loadURL('http://localhost:3000')

  // Open the DevTools.
  // mainWindow.webContents.openDevTools()
}

const createTray = () => {
  const icon = path.join(__dirname, 'assets/nozdive.png')
  const nImage= nativeImage.createFromPath(icon)

  tray = new Tray(nImage)
  tray.on('click', (event) => toggleWindow())
}

const toggleWindow = () => {
  window.isVisible() ? window.hide() : window.show()
}


// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  ipcMain.on('minimize-event', ()  => window.minimize())
  createTray()
  createWindow()

  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit()
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

const store = new Store()

这里是渲染函数。

import React, {useState} from 'react'
import { Box, Typography } from '@mui/material'
import MenuIcon from '@mui/icons-material/Menu';
import CloseIcon from '@mui/icons-material/Close';
import FullscreenIcon from '@mui/icons-material/Fullscreen';
import MinimizeIcon from '@mui/icons-material/Minimize';
// import FullscreenExitIcon from '@mui/icons-material/FullscreenExit';
import colors from '../config/colors';

const {ipcRenderer} = window.require('electron')

export default function TitleBar({toggleDrawer}) {
  const [isActive, setIsActive] = useState()
  const [isminimized, setIsminimized] = useState()
  const [isFullScreen, setIsFullScreen] = useState(false)

  const handleMinimize = () => {
    toggleDrawer()
    // ipcRenderer.invoke('minimize-event')
  }

  const toggleIsFullScreen = () => {
    const state = isFullScreen
    setIsFullScreen(!state)
  }

  const handleClose = () => {
    toggleDrawer()
  }

  return (
    <Box sx={styles.headerBox}>
      <MenuIcon 
        sx={styles.headerFont}
        onClick={toggleDrawer}
      />
      <Box sx={styles.textbox}>
        <Typography sx={styles.headerFont}>Nozdive's Program!</Typography>
      </Box>
      <Box sx={styles.windowControl}>
          <MinimizeIcon 
            sx={styles.headerFont}
            onClick={handleMinimize}
          />
          <FullscreenIcon 
            sx={styles.headerFont}
            onClick={toggleIsFullScreen}
          />
          <CloseIcon 
            sx={styles.headerFont}
            onClick={handleClose}
          />
      </Box>
    </Box>
  )
}

const styles = {
  headerBox: {
    alignItems: 'center',
    backgroundColor: colors.secondary,
    display: 'flex',
    height: 30,
    width: '100vw',
  },
  headerFont: {
    color: colors.tertiary,
    fontSize: 30,
    padding: 1,
  },
  textbox: {
    display: 'flex',
    width: '100vw',
    alignItems: 'center',
    justifyContent: 'center',
  },
  windowControl: {
    display: 'flex',
    justifyContent: 'center',
  },
}

您应该在 preload.js

中添加以下代码
const { ipcRenderer } = require("electron");

process.once("loaded", () => {
  window.ipcRenderer = ipcRenderer;
});