Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/hardchor/electron-redux
Use redux in the main and browser processes in electron
https://github.com/hardchor/electron-redux
electron klarna-featured redux
Last synced: about 2 months ago
JSON representation
Use redux in the main and browser processes in electron
- Host: GitHub
- URL: https://github.com/hardchor/electron-redux
- Owner: klarna
- License: mit
- Created: 2016-10-11T17:58:49.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2024-05-14T18:39:52.000Z (5 months ago)
- Last Synced: 2024-05-28T16:07:46.460Z (4 months ago)
- Topics: electron, klarna-featured, redux
- Language: JavaScript
- Homepage:
- Size: 2.84 MB
- Stars: 741
- Watchers: 8
- Forks: 94
- Open Issues: 58
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
Awesome Lists containing this project
- awesome-electron - electron-redux - Synchronize Redux state across windows. ![](https://img.shields.io/github/stars/hardchor/electron-redux.svg?style=social&label=Star) (Library / Uncategorized)
- awesome-electron-zh - electron-redux - Synchronize Redux state across windows. (Tools / For Electron)
README
# electron-redux
[![CircleCI](https://circleci.com/gh/klarna/electron-redux/tree/master.svg?style=svg)](https://circleci.com/gh/klarna/electron-redux/tree/master)
- [electron-redux](#electron-redux)
- [Motivation](#motivation)
- [The solution](#the-solution)
- [Install](#install)
- [Actions](#actions)
- [Local actions (renderer process)](#local-actions-renderer-process)
- [Aliased actions (main process)](#aliased-actions-main-process)
- [Blacklisted actions](#blacklisted-actions)
- [F.A.Q.](#faq)
- [Contributions](#contributions)
- [Contributors](#contributors)## Motivation
Using redux with electron poses a couple of problems. Processes ([main](https://github.com/electron/electron/blob/master/docs/tutorial/quick-start.md#main-process) and [renderer](https://github.com/electron/electron/blob/master/docs/tutorial/quick-start.md#renderer-process)) are completely isolated, and the only mode of communication is [IPC](https://github.com/electron/electron/blob/master/docs/api/ipc-main.md).
- Where do you keep the state?
- How do you keep the state in sync across processes?### The solution
`electron-redux` offers an easy to use solution. The redux store on the main process becomes the single source of truth, and stores in the renderer processes become mere proxies. See [under the hood](#under-the-hood).
![electron-redux basic](https://cloud.githubusercontent.com/assets/307162/20675737/385ce59e-b585-11e6-947e-3867e77c783d.png)
## Install
```
npm install --save electron-redux
````electron-redux` comes as redux middleware that is really easy to apply:
```javascript
// in the main store
import { forwardToRenderer, triggerAlias, replayActionMain } from 'electron-redux';const todoApp = combineReducers(reducers);
const store = createStore(
todoApp,
initialState, // optional
applyMiddleware(
triggerAlias, // optional, see below
...otherMiddleware,
forwardToRenderer, // IMPORTANT! This goes last
),
);replayActionMain(store);
``````javascript
// in the renderer store
import { forwardToMain, replayActionRenderer, getInitialStateRenderer } from 'electron-redux';const todoApp = combineReducers(reducers);
const initialState = getInitialStateRenderer();const store = createStore(
todoApp,
initialState,
applyMiddleware(
forwardToMain, // IMPORTANT! This goes first
...otherMiddleware,
),
);replayActionRenderer(store);
```Check out [timesheets](https://github.com/hardchor/timesheets/blob/4991fd472dbb12b0c6e6806c6a01ea3385ab5979/app/shared/store/configureStore.js) for a more advanced example.
And that's it! You are now ready to fire actions without having to worry about synchronising your state between processes.
## Actions
Actions fired **MUST** be [FSA](https://github.com/acdlite/flux-standard-action#example)-compliant, i.e. have a `type` and `payload` property. Any actions not passing this test will be ignored and simply passed through to the next middleware.
> NB: `redux-thunk` is not FSA-compliant out of the box, but can still produce compatible actions once the async action fires.
Furthermore, actions (and that includes `payload`s) **MUST** be (de-)serialisable, i.e. either POJOs (simple `object`s - that excludes native JavaScript or DOM objects like `FileList`, `Map`, etc.), `array`s, or primitives. For workarounds, check out [aliased actions](#aliased-actions-main-process)
### Local actions (renderer process)
By default, all actions are being broadcast from the main store to the renderer processes. However, some state should only live in the renderer (e.g. `isPanelOpen`). `electron-redux` introduces the concept of action scopes.
To stop an action from propagating from renderer to main store, simply set the scope to `local`:
```javascript
function myLocalActionCreator() {
return {
type: 'MY_ACTION',
payload: 123,
meta: {
scope: 'local',
},
};
}
```### Aliased actions (main process)
Most actions will originate from the renderer side, but not all should be executed there as well. A great example is fetching of data from an external source, e.g. using [promise middleware](https://github.com/acdlite/redux-promise), which should only ever be executed once (i.e. in the main process). This can be achieved using the `triggerAlias` middleware mentioned [above](#install).
Using the `createAliasedAction` helper, you can quite easily create actions that are are only being executed in the main process, and the result of which is being broadcast to the renderer processes.
```javascript
import { createAliasedAction } from 'electron-redux';export const importGithubProjects = createAliasedAction(
'IMPORT_GITHUB_PROJECTS', // unique identifier
(accessToken, repoFullName) => ({
type: 'IMPORT_GITHUB_PROJECTS',
payload: importProjects(accessToken, repoFullName),
}),
);
```Check out [timesheets](https://github.com/hardchor/timesheets/blob/4ccaf08dee4e1a02850b5bf36e37c537fef7d710/app/shared/actions/github.js) for more examples.
### Blacklisted actions
By default actions of certain type (e.g. starting with '@@') are not propagated to the main thread. You can change this behaviour by using `forwardToMainWithParams` function.
```javascript
// in the renderer store
import {
forwardToMainWithParams,
replayActionRenderer,
getInitialStateRenderer,
} from 'electron-redux';const todoApp = combineReducers(reducers);
const initialState = getInitialStateRenderer();const store = createStore(
todoApp,
initialState,
applyMiddleware(
forwardToMainWithParams(), // IMPORTANT! This goes first
...otherMiddleware,
),
);replayActionRenderer(store);
```You can specify patterns for actions that should not be propagated to the main thread.
```javascript
forwardToMainWithParams({
blacklist: [/^@@/, /^redux-form/],
});
```## F.A.Q
### `electron-redux` crashes with electron 10.x
As of Electron 10, the `remote` module is removed by default.
We can get it back by adding `enableRemoteModule=true` to the `webPreferences`:
```js
const w = new BrowserWindow({
webPreferences: {
enableRemoteModule: true,
},
});
```## Contributions
Contributions via [issues](https://github.com/klarna/electron-redux/issues/new) or [pull requests](https://github.com/klarna/electron-redux/compare) are hugely welcome!
Feel free to let me know whether you're successfully using `electron-redux` in your project and I'm happy to add them here as well!
## Contributors
Special thanks go out to:
- [Charlie Hess](https://github.com/CharlieHess)
- [Roman Paradeev](https://github.com/sameoldmadness)
- [Pelle Jacobs](https://github.com/pellejacobs)
- [Victor Quiroz Castro](https://github.com/victorhqc)
- [musou1500](https://github.com/musou1500)
- [Andreas Dolk](https://github.com/Treverix)
- Everyone who has contributed by [asking questions & raising issues](https://github.com/klarna/electron-redux/issues?q=is%3Aissue+is%3Aclosed)