Reactjs 远处的恐怖动作:电子&;React useEffect-无法取消订阅IPC事件

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

我在使用Electron的
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/更新其文档。我在这里的问题仍未解决,但对于那些感兴趣的人来说: