我正在开发一个前端使用React的电子应用程序。该应用程序将显示几个文件夹中的文件。然后它将允许用户使用一些按钮删除文件或将文件复制到另一个文件夹。我已经知道如何使用按钮删除或复制文件。但我不知道如何在删除或复制文件后更新GUI。我一直在遵循以下教程:https://medium.com/jspoint/working-with-files-i-o-in-an-electron-application-b4d2de403f54
下面是我的后端electron.js
的相关部分:
// Module to control the application lifecycle and the native browser window.
const {
app,
BrowserWindow,
protocol,
nativeTheme,
ipcMain,
} = require("electron");
const path = require("path");
const url = require("url");
const io = require("../electron/io");
// Create the native browser window.
function createWindow() {
const mainWindow = new BrowserWindow({
width: 1200,
height: 800,
autoHideMenuBar: true,
resizable: false,
// Set the path of an additional "preload" script that can be used to
// communicate between node-land and browser-land.
webPreferences: {
preload: path.join(__dirname, "preload.js"),
},
});
nativeTheme.themeSource = "dark";
// return list of current front end files
ipcMain.handle("app:get-current-FE-files", () => {
return io.getFiles("C:/test");
});
// return list of previous front end files
ipcMain.handle("app:get-previous-FE-files", () => {
return io.getFiles("C:/test-previous-files");
});
ipcMain.handle("app:delete-all-folder-contents", (event, folder) => {
// console.log({ event });
// console.log({ folder });
let folderWithFiles = '';
if (folder === 'prodorchtest-previous-folder') {
folderWithFiles = 'C:/test-previous-files';
}
return io.deleteAllFilesInFolder(folderWithFiles);
});
ipcMain.handle("app:copy-all-folder-contents", (event, fromTo) => {
console.log({ fromTo })
if (fromTo === 'prodorchtest-to-previous-folder') {
return io.copyFilesBetweenFolders('C:/test', 'C:/test-previous-files');
}
});
// In production, set the initial browser path to the local bundle generated
// by the Create React App build process.
// In development, set it to localhost to allow live/hot-reloading.
const appURL = app.isPackaged
? url.format({
pathname: path.join(__dirname, "index.html"),
protocol: "file:",
slashes: true,
})
: "http://localhost:3006";
mainWindow.loadURL(appURL);
io.watchFiles(mainWindow);
在io.js
中,watchFiles
是这样的:
// watch files from the application's storage directory
exports.watchFiles = (win) => {
const prevFEFolder = 'C:/test-previous-files';
// chokidar.watch(prevFEFolder).on("unlink", (filepath) => {
// console.log('unlink called with: ', filepath)
// //win.webContents.send("app:delete-file", path.parse(filepath).base);
// });
chokidar.watch(prevFEFolder).on('add', (path) => {
console.log({ path });
win.webContents.send("app:add-file", path);
});
};
下面是我的preload.js
:
// All of the Node.js APIs are available in the preload process.
// It has the same sandbox as a Chrome extension.
const { contextBridge, ipcRenderer } = require("electron");
// As an example, here we use the exposeInMainWorld API to expose the browsers
// and node versions to the main window.
// They'll be accessible at "window.versions".
process.once("loaded", () => {
contextBridge.exposeInMainWorld("versions", process.versions);
});
contextBridge.exposeInMainWorld("fsInfo", {
getCurrentFEDirContents: () => ipcRenderer.invoke("app:get-current-FE-files"),
getPreviousFEDirContents: () =>
ipcRenderer.invoke("app:get-previous-FE-files"),
});
contextBridge.exposeInMainWorld("fsActions", {
deleteAllFolderContents: (folder) => ipcRenderer.invoke("app:delete-all-folder-contents", folder),
copyAllFolderContents: (fromTo) => ipcRenderer.invoke("app:copy-all-folder-contents", fromTo),
});
我不确定我是否应该在那里添加前端功能来监视文件更改,或者它是否应该在App.js
中。
这是我的App.js
的第一部分:
import React, { useEffect, useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faArrowRight, faFileImage } from '@fortawesome/free-solid-svg-icons';
import folder from './img/folder.png';
import ErrorBoundary from './ErrorBoundary';
// this import causes errors
// const { ipcRenderer } = require('electron');
const App = () => {
// these state arrays are what I would want to update when changes are made with deleting
// or copying files
const [currentFEFiles, setCurrentFEFiles] = useState([]);
const [previousFEFiles, setPreviousFEFiles] = useState([]);
// useEffect(() => {
// // Listen for the event
// ipcRenderer.on('app:add-file', (event, arg) => {
// console.log({event, arg})
// });
// // Clean the listener after the component is dismounted
// return () => {
// ipcRenderer.removeAllListeners();
// };
// }, []);
const getTheFiles = async () => {
try {
const currentFilelist = await window.fsInfo.getCurrentFEDirContents();
console.log({ currentFilelist });
currentFilelist.sort((a, b) =>
a.isDir < b.isDir ? 1 : b.isDir < a.isDir ? -1 : a.name - b.name
);
setCurrentFEFiles(currentFilelist);
const previousFileList = await window.fsInfo.getPreviousFEDirContents();
previousFileList.sort((a, b) =>
a.isDir < b.isDir ? 1 : b.isDir < a.isDir ? -1 : a.name - b.name
);
setPreviousFEFiles(previousFileList);
} catch (e) {
console.log({ e });
setCurrentFEFiles([]);
}
// setCurrentFEFiles([]);
};
useEffect(() => {
getTheFiles();
//window.fsInfo.getDirContents().then(r => console.log({r}));
// console.log({ filelist });
}, []);
const deleteFolderContents = async (folder) => {
await window.fsActions.deleteAllFolderContents(folder);
};
const copyFolderContents = async (fromTo) => {
await window.fsActions.copyAllFolderContents(fromTo);
// maybe this is where I would add some code to update the state?
};
1条答案
按热度按时间mxg2im7a1#
问题应该只出在
React
部分。在检查您的代码
App.js
后,似乎您的代码没有通知React
在文件更改后重新渲染。这里的
useEffect
只运行一次。它不会在每次更改文件时刷新用户界面。
即使在
getTheFiles
中更改了状态数组,getTheFiles
也没有机会重新调用。您可以尝试在
await
行下方的deleteFolderContents
和copyFolderContents
中添加getTheFiles()
,因为getTheFiles
中的setXXX
将触发UI重新呈现。