Electronにおいてメインプロセスでアプリケーションメニューを設定し、そのメニューが選択された場合の処理をreduxのフローで制御したいなと思い、やり方を調べました。
公式ドキュメントなどは組込処理の呼び出しばかりで、やり方を見つけるのに苦労しました。
1. メインプロセスでメニューイベントをハンドリングし、reduxアプリケーションへ橋渡し
main.js
app.on('ready', () => {
mainWindow = new BrowserWindow({});
menu = Menu.buildFromTemplate([{
label: 'Awesome menu',
submenu: [{
label: 'my menu',
click() {
// 適当なイベント名を付けて送ります。引数があれば第二引数以降に渡します。
mainWindow.webContents.send('my-menu', "hoge");
}
}]
}]);
Menu.setApplicationMenu(menu);
})
以下、electron-react-boilerplateを例に説明します。
2. reduxアプリケーションのエントリポイント(storeを作っているところ)
app/index.js
// ipcRendererをインポート
import { ipcRenderer } from 'electron';
import configureStore from './store/configureStore';
const store = configureStore();
// ipcRendererに対してイベントハンドラを登録。
ipcRenderer.on('my-menu', (event, param) => {
// イベントをdispatchする。引数はactionで返すものと同じ形式で `type + 任意の引数` (typeは適宜const化)
// 場合によってはactionに書いて、ここではactionを呼び出す形のほうがキレイかも
store.dispatch({ type: 'MY_MENU', param });
});
3. reducerで処理する
app/reducer/counter.js(適切な場所がなかったのでcouter.jsを間借り)
export default function counter(state = {}, action) {
switch (action.type) {
case 'MY_MENU':
// メニューの処理
console.log(`my awesome menu param:${action.param}`);
// 必要に応じて新しいstateを作って返す
return state;
default:
return state;
}
}