Reactjs 远处的恐怖动作:电子&;React useEffect-无法取消订阅IPC事件
我在使用Electron的Reactjs 远处的恐怖动作:电子&;React useEffect-无法取消订阅IPC事件,reactjs,electron,ipcrenderer,Reactjs,Electron,Ipcrenderer,我在使用Electron的ipcRenderer和React的useEffect时遇到了奇怪的行为。 在我的electron应用程序中,我有以下代码: import React, { useEffect } from 'react' const electron = window.require('electron'); const ipcRenderer = electron.ipcRenderer; ... const someValueThatChanges = props.someV
ipcRenderer
和React的useEffect
时遇到了奇怪的行为。
在我的electron应用程序中,我有以下代码:
import React, { useEffect } from 'react'
const electron = window.require('electron');
const ipcRenderer = electron.ipcRenderer;
...
const someValueThatChanges = props.someValue;
useEffect(() => {
const myEventName = 'some-event-name';
console.log(`Using effect. There are currently ${ipcRenderer.listenerCount(eventName)} listeners.`);
console.log(`Value that has changed: ${someValueThatChanges}.`);
ipcRenderer.addListener(myEventName, myEventHandler);
console.log('Added a new listener.');
// Should clean up the effect (remove the listener) when the effect is called again.
return () => {
ipcRenderer.removeListener(myEventName, myEventHandler)
console.log('Cleaned up event handler.');
}
}, [ someValueThatChanges ]);
function myEventHandler() {
console.log('Handled event');
}
上面的代码应该监听Electron的主进程通过mainWindow.webContents.send('some-event-name')触发的some-event-name
事件
和console.log(…)
表示已处理事件的消息
这与最初运行效果时的预期效果一样。添加一个侦听器,稍后引发事件,并将字符串'Handled event'
打印到控制台。但是当somevaluethatthanges
变量被分配了一个不同的值并且再次引发事件时,“已处理事件”字符串将被打印到控制台两次(旧的侦听器似乎没有被删除)
当useffect返回/清除函数中包含removeListener(…)
调用时,带有listenerCount(eventName)
调用的行按预期返回0。删除RemovelListener(…)
调用时,listenerCount(eventName)
调用返回一个值,该值在未删除侦听器时按预期递增(例如0、1、2)
这是真正奇怪的部分。在任何一种情况下,无论我是否包括对
removeListener(…)
的调用,都会在运行useEffect时调用myEventHandler
函数。换句话说,Electron报告说没有事件侦听器,但是以前的侦听器似乎仍然调用了myEventHandler。这是Electron中的一个bug,还是我遗漏了什么?请不要尝试使用ipcRenderer.addListener
,而是尝试ipcRenderer.on
useEffect(() => {
ipcRenderer.send('send-command', 'ping');
ipcRenderer.on('get-command', (event, data) => {
console.log('data', data);
});
return () => {
ipcRenderer.removeAllListeners('get-command');
};
}, []);
我相信,医生改变了
ipcRenderer.removeAllListeners
接受单个字符串而不是字符串源数组,永远不要尝试使用ipcRenderer.addListener
,而是尝试ipcRenderer.on
useEffect(() => {
ipcRenderer.send('send-command', 'ping');
ipcRenderer.on('get-command', (event, data) => {
console.log('data', data);
});
return () => {
ipcRenderer.removeAllListeners('get-command');
};
}, []);
我相信,医生改变了
ipcRenderer.RemoveAllListener
接受单个字符串而不是字符串源数组,可能尝试使用on()
而不是addListener()
?感谢您的建议。两种我都试过了。根据定义EventEmitter
的NodeJs文档,on
和off
分别是addListener
和removeListener
的别名:。这带来了另一件奇怪的事情:渲染器API与NodeJS EventEmitter API不太匹配。刚刚够烦人的了。例如,ipcRenderer支持on()
但不支持off()
,以及RemovelListener()
但不支持addListener()
。nodejsapi支持所有四种。也就是说,这四个函数在上使用时都不会抛出任何错误。因此,Electron中支持off
和addListener
,但没有文档记录,或者它们不受支持且无提示地失败。我在Electron repo上创建了一个功能请求,以标准化IPC渲染器API/更新其文档。我这里的问题仍然没有解决,但是对于那些感兴趣的人来说:也许可以尝试使用on()
而不是addListener()
?谢谢你的建议。两种我都试过了。根据定义EventEmitter
的NodeJs文档,on
和off
分别是addListener
和removeListener
的别名:。这带来了另一件奇怪的事情:渲染器API与NodeJS EventEmitter API不太匹配。刚刚够烦人的了。例如,ipcRenderer支持on()
但不支持off()
,以及RemovelListener()
但不支持addListener()
。nodejsapi支持所有四种。也就是说,这四个函数在上使用时都不会抛出任何错误。因此,Electron中支持off
和addListener
,但没有文档记录,或者它们不受支持且无提示地失败。我在Electron repo上创建了一个功能请求,以标准化IPC渲染器API/更新其文档。我在这里的问题仍未解决,但对于那些感兴趣的人来说: