Spooky Action на расстоянии: Electron & React useEffect - невозможно отписаться от событий ipcRenderer - PullRequest
1 голос
/ 11 февраля 2020

Я столкнулся со странным поведением при использовании Electron's ipcRenderer с React's useEffect. В моем электронном приложении у меня есть следующий код:

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');
}

Предполагается, что приведенный выше код прослушивает событие some-event-name, инициируемое основным процессом Electron с mainWindow.webContents.send('some-event-name'); и console.log(...) сообщением, начинающим событие было обработано.

Работает, как и ожидалось, при первоначальном запуске эффекта. Добавляется прослушиватель, событие вызывается позднее, и строка 'Handled event' выводится на консоль. Но когда переменной someValueThatChanges присвоено другое значение и событие вызывается во второй раз, строка «Обработанное событие» выводится на консоль дважды (старый слушатель, похоже, не имеет был удален).

Строка с вызовом listenerCount(eventName) возвращает 0, как и ожидалось, когда вызов removeListener(...) включен в функцию возврата / очистки useEffect. Когда вызов removeListener(...) удален, вызов listenerCount(eventName) возвращает значение, которое увеличивается, как и ожидалось (например, 0, 1, 2), поскольку слушатели не удаляются.

Вот действительно странная часть. В случае или , независимо от того, включаю ли я вызов removeListener(...), функция myEventHandler всегда вызывается столько раз, сколько было выполнено useEffect. Другими словами, Electron сообщает, что нет прослушивателей событий, но myEventHandler по-прежнему вызывается предыдущими слушателями. Это ошибка в Electron, или я что-то упустил?

...