YouTip LogoYouTip

React Electron

React + Electron Practical Project | Beginner's Tutorial\n\nThis chapter we will use React + Electron to create a notes application. This practical project is named ReactElectronNotes, featuring multi-window, system tray, file operations, and IPC communication. It is a very suitable project for beginners to practice.\n\nIf you are not familiar with React yet, you can first refer to: (#).\n\nThe **ReactElectronNotes** project will teach you to build a **cross-platform desktop notes application** from scratch, including the following features:\n\n* React frontend rendering\n* Electron main process management\n* IPC communication (main process ↔ renderer process)\n* Local data persistence for notes (`electron-store`)\n* System tray and menu integration\n\n### Project Structure Explanation\n\nReactElectronNotes/β”‚β”œβ”€β”€ src/ # React source code directoryβ”œβ”€β”€ build/ # Packaged React static filesβ”œβ”€β”€ electron-main.js # Electron main processβ”œβ”€β”€ preload.js # Renderer and main process communication bridgeβ”œβ”€β”€ note.html # Child window pageβ”œβ”€β”€ note.js # Child window scriptβ”œβ”€β”€ package.json └── assets/ └── icon.png # Tray icon\n\n* * *\n\n## 1. Project Feature Overview\n\n| Feature Module | Description |\n| --- | --- |\n| Main Window | Display all notes list |\n| Child Window | New note input |\n| Local Storage | Use `electron-store` to save data |\n| System Tray | Minimize to tray, can click to bring up main interface |\n| IPC Communication | Renderer process and main process interaction, read/write data |\n\n* * *\n\n## 2. Project Initialization\n\n### 1. Create React Project\n\nnpx create-react-app ReactElectronNotes cd ReactElectronNotes\n### 2. Install Electron and Dependencies\n\nnpm install --save-dev electron electron-builder concurrently wait-on npm install electron-store\n### 3. Modify `package.json`\n\nEnsure to add Electron startup command in `scripts`:\n\n"main": "electron-main.js","scripts": { "react-start": "react-scripts start", "react-build": "react-scripts build", "electron-start": "concurrently "npm run react-start" "wait-on http://localhost:3000 && electron ."", "electron-build": "react-scripts build && electron-builder"}\n\n* * *\n\n## 3. Create Electron Main Process\n\nCreate new file `electron-main.js`:\n\n## Example\n\nconst{ app, BrowserWindow, Tray, Menu, ipcMain }= require('electron')\n\nconst path = require('path')\n\nconst Store = require('electron-store')\n\nlet mainWindow, noteWindow, tray\n\nconst store =new Store()\n\nfunction createMainWindow(){\n\n mainWindow =new BrowserWindow({\n\n width:800,\n\n height:600,\n\n webPreferences:{\n\n preload: path.join(__dirname,'preload.js'),\n\n contextIsolation:true,\n\n nodeIntegration:false\n\n}\n\n})\n\nif(process.env.NODE_ENV==='development'){\n\n mainWindow.loadURL('http://localhost:3000')\n\n}else{\n\n mainWindow.loadFile(path.join(__dirname,'build/index.html'))\n\n}\n\nmainWindow.on('minimize',(e)=>{\n\n e.preventDefault()\n\n mainWindow.hide()\n\n})\n\ncreateTray()\n\n}\n\nfunction createNoteWindow(){\n\n noteWindow =new BrowserWindow({\n\n width:400,\n\n height:300,\n\n parent: mainWindow,\n\n modal:true,\n\n webPreferences:{\n\n preload: path.join(__dirname,'preload.js'),\n\n contextIsolation:true,\n\n nodeIntegration:false\n\n}\n\n})\n\nnoteWindow.loadFile(path.join(__dirname,'note.html'))\n\n}\n\nfunction createTray(){\n\n tray =new Tray(path.join(__dirname,'assets/icon.png'))\n\nconst menu = Menu.buildFromTemplate([\n\n{ label:'Show Window', click:()=> mainWindow.show()},\n\n{ label:'Exit', click:()=> app.quit()}\n\n])\n\n tray.setToolTip('ReactElectronNotes')\n\n tray.setContextMenu(menu)\n\n}\n\napp.whenReady().then(createMainWindow)\n\nipcMain.handle('get-notes',()=>{\n\nreturn store.get('notes',[])\n\n})\n\nipcMain.on('save-note',(event, note)=>{\n\nconst notes = store.get('notes',[])\n\n notes.push(note)\n\n store.set('notes', notes)\n\n mainWindow.webContents.send('update-notes', notes)\n\n})\n\napp.on('window-all-closed',()=>{\n\nif(process.platform!=='darwin') app.quit()\n\n})\n\n* * *\n\n## 4. Create Preload Script\n\nCreate new `preload.js`:\n\n## Example\n\nconst{ contextBridge, ipcRenderer }= require('electron')\n\ncontextBridge.exposeInMainWorld('electronAPI',{\n\n getNotes:()=> ipcRenderer.invoke('get-notes'),\n\n saveNote:(note)=> ipcRenderer.send('save-note', note),\n\n onUpdateNotes:(callback)=> ipcRenderer.on('update-notes', callback)\n\n})\n\n**Explanation:**\n\nSafely expose API to renderer process through `contextBridge`.\n\n* * *\n\n## **5. React Frontend Interface**\n\n### `src/App.js`\n\n## Example\n\nimport React,{ useState, useEffect } from 'react'\n\nfunction App(){\n\nconst[notes, setNotes]= useState([])\n\nuseEffect(()=>{\n\n window.electronAPI.getNotes().then(setNotes)\n\n window.electronAPI.onUpdateNotes((_event, newNotes)=> setNotes(newNotes))\n\n},[])\n\nconst openNoteWindow =()=>{\n\n window.open('note.html','New Note','width=400,height=300')\n\n}\n\nreturn(\n\n
\n\n

My Notes

\n\n\n\n
    \n\n{notes.map((n, i)=>(\n\n
  • {n}
  • \n\n))}\n\n
\n\n
\n\n)\n\n}\n\nexport default App\n\n### Create new `note.html` and `note.js`\n\n#### `note.html`\n\n## Example\n\nNew Note\n\n

New Note

\n\n
\n\n\n\n#### `note.js`\n\n## Example\n\nconst saveBtn = document.getElementById('saveBtn')\n\n saveBtn.addEventListener('click',()=>{\n\nconst note = document.getElementById('note').value\n\nif(note.trim()){\n\n window.electronAPI.saveNote(note)\n\n window.close()\n\n}\n\n})\n\n* * *\n\n## 6. Run and Package\n\n### [](#)Start Development Environment\n\nnpm run electron-start\nAfter opening, the React main window will appear. You can click "New Note" to pop up the input window.\n\n### Package for Distribution\n\nnpm run electron-build\nThis will generate cross-platform executable files (`.exe`, `.app`, `.AppImage`, etc.).\n\n* * *\n\n## 7. Extension Directions\n\n| Feature | Approach |\n| --- | --- |\n| Markdown Support | Use `react-markdown` to render content |\n| Data Search | Implement local search through `filter()` on React side |\n| Auto Save | Listen to input box `onChange` for automatic saving |\n| Cloud Sync | Combine with Firebase or self-built REST API |\n| Shortcut Keys | Use `globalShortcut` to register Ctrl+N for new note |
← Python Design Pattern TutorialElectron Apis β†’