I have encountered strange behavior when using Electron's ipcRenderer
with React's useEffect
.
Within my electron app, I have the following code:
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');
}
The code above is supposed to listen to the some-event-name
event fired by Electron's main process with mainWindow.webContents.send('some-event-name');
and console.log(...)
a message inicating that the event was handled.
This works as expected when the effect is initially run. A listener is added, the event is raised at a later time, and the string 'Handled event'
is printed to to the console. But when the someValueThatChanges
variable is assigned a different value and the event is raised for a second time, the 'Handled event' string is printed out to the console twice (the old listener does not appear to have been removed).
The line with the listenerCount(eventName)
call returns 0 as expected when the removeListener(...)
call is included in the useEffect return/cleanup function. When the removeListener(...)
call is removed, the listenerCount(eventName)
call returns a value that is incremented as expected (e.g. 0, 1, 2) as listeners are not removed.
Here's the really weird part. In either case, whether or not I include the call to removeListener(...)
, the myEventHandler
function is always called for as many times as useEffect has been run. In other words, Electron reports that there are no event listeners, but myEventHandler
still seems to be called by the previous listeners. Is this a bug in Electron, or am I missing something?