Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change the Redux state based on an Electron menu click?

I'm building an Electron application based on React and Redux. I'm starting with the electron-react-boilerplate, which is pretty minimalistic and easy to understand.

I want the user to open a file on the Electron menu, and as a result, I want to call a reducer and change the Redux application state. Pretty simple concept.

The problem is that I don't know how to change the Redux state from outside my root component. The Electron menu is defined in the main.js file. The root component is defined in the index.js file, together with the Redux state (the store variable).

In the main.js file, I want to do something like this:

  submenu: [{
    label: '&Open',
    accelerator: 'Ctrl+O',
    click: function() {
        // I want to change my app Redux state here. But I don't know how.
    }
  }

Any idea?

like image 740
André Pena Avatar asked Feb 20 '16 21:02

André Pena


People also ask

How do I change my Redux state?

The state can only be changed by emitting an action. The state tree is never mutated directly instead you use pure functions called reducers. A reducer takes the current state tree and an action as arguments and returns the resulting state tree.

Can Redux state be manipulated?

Yes it can be easily manipulated.

How do you define a state in Redux?

A state in Redux is a JavaScript object, where the internal state of the application is stored as its properties, e.g. which user is logged on. After having logged in, the user of your application may navigate to different pages in your application, but you need to remember somehow, who that user is.

Can we use Redux in electron?

Electron applications can use Redux like a web application in the renderer processes, but each store is sandboxed.


2 Answers

You could obtain the filename in the main process and then send it to the renderer process via Electron IPC, for example:

In main.js

// mainWindow = new BrowserWindow();

submenu: [{
  label: '&Open',
  accelerator: 'Ctrl+O',
  click: () => {
    // popup a dialog to let the user select a file
    // ...
    // then send the filename to the renderer process
    mainWindow.webContents.send('open-file', selectedFilename);
  }
}]

In index.js

import { ipcRenderer } from 'electron';

ipcRenderer.on('open-file', (event, filename) => {
  store.dispatch({ type: 'OPEN_FILE', filename });
});
like image 120
Vadim Macagon Avatar answered Sep 23 '22 15:09

Vadim Macagon


The other option is to build your menu on the renderer side (in index.js) using the remote module, then you could call the dispatcher directly from the click callback.

like image 25
DaveJ Avatar answered Sep 21 '22 15:09

DaveJ