Loo*_*173 1 events ipc reactjs electron
我将 Electron 13 与 React 17 结合使用。我已设置nodeIntegration为 false 和contextIsolationtrue,因此我使用一个preload.js文件来公开 API 以在主进程和渲染器进程之间进行通信。
我必须使用此 API 监听 React 组件中的 IPC 消息。然而,每次安装(或重新渲染)我的组件时,Electron 都会创建一个新的 IPC 事件侦听器,从而导致内存泄漏。
预加载.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));
}
}
});
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
如何取消注册通过创建的事件侦听器window.api.receive()?
Loo*_*173 10
GitHub 上的这个问题正好解决了此类问题。简而言之,将创建的事件侦听器preload.js分配给一个变量,以便脚本可以返回回调以删除事件侦听器。
以下是如何执行此操作的示例:
预加载.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);
};
}
},
});
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2211 次 |
| 最近记录: |