我使用带有React 17的电子13。我将nodeIntegration设置为false,contextIsolation设置为true,因此我使用preload.js文件公开一个API,以在主进程和呈现程序进程之间进行通信。
我必须使用此API在React组件中侦听IPC消息。然而,每次我的组件被挂载(或重新呈现)时,电子都会创建一个新的IPC事件侦听器,从而导致内存泄漏。
preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('api', {
send: (channel, data) => {
// Whitelist channels
let validChannels = ['toMain'];
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data);
}
},
receive: (channel, func) => {
let validChannels = ['fromMain'];
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`
ipcRenderer.on(channel, (event, ...args) => func(...args));
}
}
});ReactComponent.js
import { useEffect, useRef } from 'react';
const ReactComponent = () => {
const _isMounted = useRef(true);
const exampleFunction = () => {
window.api.send('toMain');
};
window.api.receive('fromMain', function (data) {
if (_isMounted.current) {
// Process `data`...
}
});
useEffect(() => {
exampleFunction();
// Another IPC call
window.api.send('toMain', ['example']);
window.api.receive('fromMain', function (data) {
// Process `data`...
});
return () => {
_isMounted.current = false;
// Somehow I should remove the IPC event listeners here,
// but I don't know how, since (I think) they are created
// in the `preload.js` file...
};
}, []);
return (
// JSX
);
};
export default ReactComponent;如何取消注册通过window.api.receive()创建的事件侦听器
发布于 2021-08-26 17:03:26
GitHub上的这个问题精确地解决了这些问题。简而言之,在preload.js中创建的事件侦听器被分配给一个变量,以便脚本可以返回一个回调以删除事件侦听器。
下面是如何执行此操作的示例:
preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('api', {
// ...
receive: (channel, func) => {
let validChannels = ['fromMain'];
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`
const subscription = (event, ...args) => func(...args);
ipcRenderer.on(channel, subscription);
return () => {
ipcRenderer.removeListener(channel, subscription);
};
}
},
});ReactComponent.js
import { useEffect } from 'react';
const ReactComponent = () => {
const onEvent = (data) => {
// Process `data`...
};
useEffect(() => {
const removeEventListener = window.api.receive('fromMain', (data) => onEvent(data));
// ...
return () => {
removeEventListener();
};
}, []);
return (
// JSX
);
};
export default ReactComponent;https://stackoverflow.com/questions/68940343
复制相似问题