Open mrfambo opened 3 years ago
Sorry that the question is out of scope of this library...
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.
@TeeGree, thanks for the helpful information. I'll reopen this issue, so that others can benefit from your comment. :)
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>)
}
Can we use ipcRenderer in React App?