Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use ipcRenderer and ipcMain? #28

Open
mrfambo opened this issue Jul 15, 2021 · 4 comments
Open

How to use ipcRenderer and ipcMain? #28

mrfambo opened this issue Jul 15, 2021 · 4 comments

Comments

@mrfambo
Copy link

mrfambo commented Jul 15, 2021

Can we use ipcRenderer in React App?

@yhirose
Copy link
Owner

yhirose commented Jul 15, 2021

Sorry that the question is out of scope of this library...

@yhirose yhirose closed this as completed Jul 15, 2021
@TeeGree
Copy link

TeeGree commented Jul 4, 2022

For anyone looking to use ipcRenderer with an Electron app built with TypeScript and React (following the directions in this repository's readme), I wanted to detail the steps I used.

Create a preload.ts file in the electron/ folder containing the following:

import { contextBridge, ipcRenderer } from 'electron';

contextBridge.exposeInMainWorld('electron', {
    doThing: () => ipcRenderer.invoke('do-thing')
});

Include that preload file in your main.ts file and properly handle the ipc invocation.

import { app, BrowserWindow, ipcMain } from 'electron';

...

win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
        nodeIntegration: true,
        // Include the .js file, since it will be compiled from .ts by the time it is used by electron
        preload: __dirname + '/preload.js'
    }
});

...

ipcMain.handle('do-thing', (event, message) => {
    console.log('Hello, World!');
});

With these steps, the window.electron.doThing() function is now available for use in your React components, but TypeScript won't recognize it. To get the typing working properly, you can add a .d.ts file with the definition in the src/ folder.`

Here is a sample renderer.d.ts:

export interface IElectronAPI {
    doThing: () => void,
}

declare global {
    interface Window {
        electron: IElectronAPI
    }
}

Finally, you can use the doThing() function in your React component.
App.tsx:

import logo from './logo.svg';
import './App.css';
import Button from '@mui/material/Button';


function App() {
  const doThing = () => {
    window.electron.doThing();
  }

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <Button onClick={doThing}>Click me</Button>
      </header>
    </div>
  );
}

export default App;

I hope this helps! I spent a lot of time off and on this past couple months trying to find a way to actually combine TypeScript, React, Electron, and Material UI and still be able to access the file system, so I am hoping to save time for others looking to do the same. This library had most of the moving pieces close to correct, but I had to do some digging to figure out the IPC stuff.

@yhirose
Copy link
Owner

yhirose commented Jul 4, 2022

@TeeGree, thanks for the helpful information. I'll reopen this issue, so that others can benefit from your comment. :)

@yhirose yhirose reopened this Jul 4, 2022
@codestitch
Copy link

codestitch commented Sep 23, 2022

On my end, I didn't use preload.js to create exposedApi, instead I used the IpcRenderer directly in ReactApp.

import { IpcRenderer } from "electron";

export const ipcRenderer: IpcRenderer = window.require("electron").ipcRenderer;

then I can immediately use the ipc's .send() and .on() function in any of my react pages.

import { ipcRenderer } from "../ipc";

export default function Shell() {
  useEffect(() => {
    ipcRenderer.on("main-menu:open", (_, data) => {
      console.log(data)
    });

    return () => {
      ipcRenderer.removeAllListeners("metadata:open");
    };
  }, []);

  const emitToMain= (item: string) => {
    ipcRenderer.send("notify", item);
  };
  
  return (<div>...</div>)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants