How to share state (react)between electron's multiple windows?
Asked Answered
C

5

8

I am developing a desktop app with react for UI and electron.

So, for now, I am fetching data from the server and saving it in the state using React's Context API to update the UI.

I am keeping the state and the function to add, remove and update state in the renderer process and with IPC I am sharing the data between renderer process through main process (as it should be).

But as the application is scaling I need a better approach. Something like a central state (if that's a thing).

P.S. can I use a database along with the Electron app if there is any real-time database such as rxdb?

Chauvin answered 16/1, 2020 at 18:48 Comment(2)
Can edit the quest and describe a bit more about your use case here? It's hard to recommend an approach without better understanding what you need.Hyoscyamus
@AlexWayne can you take a look now?Chauvin
I
2

I had this exact same problem and I used electron-redux (https://github.com/hardchor/electron-redux). I was also using react for my UI.

Impala answered 2/6, 2020 at 0:20 Comment(0)
W
2

I ran into the same situation where I needed a single redux store for all my react renderer process in electron.

I tried electron-redux but that did not work for me as react complains about the snippet of code you need to put in the renderer process.


nice solution:

After some search I ran into redux-state-sync which is a redux middleware that used to synchronize the redux store and actions across multiple react tabs, which works nicely with electron as the tabs here are the different renderer process.

The only hindrance is to initialize the store in the newly created window, that can be done by sending the store state with an ipc call from the main window that opens the new one, that dispatches an action to update the state.

This initialization approach works nicely in [email protected] , but for some reason it doesn't in react [email protected]

Wagram answered 29/4, 2022 at 0:27 Comment(0)
C
2

Electron just like the browser / Chrome can share data between tabs via shared storage (IndexedDB) by broadcasting with the Broadcast Channel API, using a Shared Web Worker, or syncing it over a server.

The challenge with just using IndexedDB is that it isn't reactive so you have to manually monitor it for changes. The challenge with the broadcast API or Shared Workers is that you need to come up with a strategy of events and handlers to ensure your state converges to the same thing between tabs--it can end up being quite a bit of code that has sneaky bugs (see CRDTs for more info).

I'd recommend trying Triplit (a project I helped develop) which is a reactive database that can run entirely locally or sync with a server. It's likely the easiest option to setup and has built in Shared Web Worker support so you get tab syncing out of the box.

Cu answered 11/6 at 13:16 Comment(0)
G
0

For my electron-react application . I discovered that if you use Redux Persist library and store to local storage or Indexed Db . You do not need ipc for syncing state . Since All windows have acces to the same storage. So you can just open a new window . and have sync state across all windows through localstorage or indexedDB by using redux persist.

You would still might want ipc for other things , but the state problem was solved for me with this .. which is huge :)

. (For the initial State when the window opens )

Glasswork answered 11/5 at 10:30 Comment(0)
S
-1

The best way to have a 'master state' is to use React-Redux.

Redux can do what Context does and more. It also has lots of libraries for listening for realtime updates from servers. The most popular at the time is React-Redux-Firebase, which connects your Redux store with your Firebase database.

Most developers agree on the fact that Redux takes some time to set up, but is definitely worth the time invested. I have personally used React-Redux-Firebase and I can assure you that all real-time updates will be in your Redux store within 250ms.

Firebase is also free up to a certain point (check Firebase Pricing).

In order to access your Redux state in a component, your need to follow 3 steps:

STEP 1: Create a mapStateToProps const that contains all the stuff you want from your store.

const mapStateToProps = state => ({
    customers: state.customers,
    books: state.books
})

STEP2: Create an actions const that contains any functions you have in an actions.js or similar file and you want to call

import { fetchCustomers } from './actions.js'

const actions = {
    fetchCustomers
}

Remember that any fetching from your API can (and should) be done from there.

STEP 3: Export your component with Redux's connect function, including your mapStateToProps and actions consts.

export default connect(mapStateToProps, actions)(myComponent);

Redux is rather complicated to be explained in a single stackoverflow answer, so I suggest you take a look at the docs or follow a tutorial. You should be able to figure everything out in your first or second day of development. It is absolutely worth the time.

Scathing answered 16/1, 2020 at 19:23 Comment(7)
But how do I sync the redux state across the multiple windows and I have implemented my own API using node and express.Chauvin
You can pass any variables or objects from your Redux store to any component in 3 simple steps. I will add them right away in my answer above.Scathing
Redux can be great, but this doesn't help with multiple electron windows that all run in different processes.Hyoscyamus
@AlexWayne yes that is what I am trying to say.Chauvin
How will it help in synchronization of the state across all electron's window?Chauvin
@Chauvin did you manage to share state between windows? Just came across same problem.Worl
@Razi, I used and tweaked a little bit electron-redux package. github.com/hardchor/electron-reduxChauvin

© 2022 - 2024 — McMap. All rights reserved.