electron-cgi icon indicating copy to clipboard operation
electron-cgi copied to clipboard

Support remove listener from connection

Open juankar1994 opened this issue 4 years ago • 3 comments

There should be a way to remove any listener that we add to the connection. Because, sometimes we want to remove the listener as well or change the listener for that specified event type.

Thanks.

juankar1994 avatar Mar 24 '20 14:03 juankar1994

Thanks @ruidfigueiredo for adding the issue in the milestone.

As a long term plan you could extends the connection events functionality based on Node.js EventEmitter.

juankar1994 avatar Mar 24 '20 22:03 juankar1994

Hi, I actually came here to submit the same request! My enterprise team is looking at using Electron-CGI in one of our projects and one of the early issues we ran into was that a React component in Electron needed to respond to an event, connection.on('myevent'), and update state. Because it had to update state, this statement had to be within the component. However, whenever the component re-rendered, we ended up re-subscribing, which caused a memory leak. For now, we've addressed this by subscribing elsewhere in code, publishing an event, and using ipcRenderer.on('myevent') in the component after first calling ipcRenderer.removeAllListeners('myevent').

NSouth avatar Jun 25 '20 00:06 NSouth

Hi @NSouth

While this feature isn't available an alternative that has worked very well for me in React is to take advantage of an EventEmitter instead of relying only the connection handlers.

That's the approach I used in Memory Ace

In preload.js you can expose the connection and the EventEmitter to React this way: https://github.com/ruidfigueiredo/MemorizeADeck/blob/master/memorize-a-deck-electron/preload.js

Then you can register on a "ElectronCGI event" this way (example from here):

export const memorizationEvents = new EventEmitter();`

//...

connection.on('memorization.complete', result => {
    memorizationEvents.emit('complete', result);
});

Then on your component (example from here):

    useEffect(() => {        
        const handleMemorizationComplete = ({ cardsMemorized, memorizationTime }) => {
            history.push({
                pathname: '/recall',
                state: {
                    cardsMemorized,
                    memorizationTime
                }
            });
        };

        memorizationEvents.on('complete', handleMemorizationComplete);

        return () => {
            memorizationEvents.off('complete', handleMemorizationComplete);    
        }
    }, [history]);

ruidfigueiredo avatar Jun 26 '20 10:06 ruidfigueiredo