reactjsreact-hookselectronreact-functional-componentipcrenderer

Electron/React cannot access component state changes in ipcRenderer listener


I am using Electron with React and I am facing a little problem.

I am creating a functional component and in the useEffect hook I subscribe to ipcRenderer to listen for when ipcMain replies.

When ipcRenderer event triggers I am unable to access the latest state updates. All state variables values inside ipcRenderer.on function contain data when the component was initially created.

In the code below customers is an array state variable. If I console.log its value every time the ipcRenderer.on is fired it is always empty. I am absolutely sure this variable is not empty inside the component's context because it contains information that is rendered in a grid. When ipcRenderer.on is triggered my grid is reset or cleared. All I am trying to do is refresh a row in the grid when ipcRenderer.on is triggered.

useEffect(() => {

    // Actions triggered in response to main process replies
    ipcRenderer.on(IPCConstants.UPDATE_SALE_CUSTOMER, (event: any, arg: IUpdateResponse) => {
    
        setIsLoading(false);

        if(!arg.success) {
            notifyError(arg.message);
            return;
        }

        setCustomers(
            customers.map(cst => {
                if(cst.CUS_CustomerId === arg.customer.CUS_CustomerId){
                    cst.RowId = `${generateRandomValue()}`;
                    cst.isActive = arg.customer.isActive;
                }
                return cst;
            })
        )
    });

    return () => {
        ipcRenderer.removeAllListeners(IPCConstants.UPDATE_SALE_CUSTOMER);
    };

}, []);

Solution

  • useEffect(() => {
    
        // Actions triggered in response to main process replies
        ipcRenderer.on(IPCConstants.UPDATE_SALE_CUSTOMER, (event: any, arg: IUpdateResponse) => {
        
            setIsLoading(false);
    
            if(!arg.success) {
                notifyError(arg.message);
                return;
            }
    
            setCustomers(
                customers.map(cst => {
                    if(cst.CUS_CustomerId === arg.customer.CUS_CustomerId){
                        cst.RowId = `${generateRandomValue()}`;
                        cst.isActive = arg.customer.isActive;
                    }
                    return cst;
                })
            )
        });
    
        return () => {
            ipcRenderer.removeAllListeners(IPCConstants.UPDATE_SALE_CUSTOMER);
        };
    
    }, [customers, otherState (if needed)]); // <= whichever state is not up to date