Meteor Redux persistence for UI states

Hi everyone, I’m currently using Redux for our app’s UI state based on most user’s recommendation (Domain state still managed by Mongo).

So my question is whenever I refresh the page the Store is reset but Meteor’s Data still exist. This is a problem because for example the user is logged in, the components shown on the page are specific for logged in users which is determined by the state loggedIn on the Redux Store. However, when I refresh, since the Store is reset, the user is considered logged out by the app even though Meteor knows the user is still logged in. So with that said, do you think I should persist the entire UI Store to Mongo? or somewhere else, like Session?

When you initialize your store client side, you can set up its initial state. Note also that as the user is received via Meteor’s pub/sub, Meteor.user() will transition from null to the current auto-logged in user. For ensuring that your loggedIn store is in sync, use a Tracker.autorun to populate your store as Meteor.user() is a reactive variable.

1 Like

Thinking of it, you can also sync your store in the LocalStorage and when your app wakes up (be it from a code refresh or reopening the app) you’re already in a connected state. When you receive the real Meteor.user() you can reconcile the real state of your loggedIn store.

@pierreeric Now that make sense, thank you for pointing that out regarding Meteor.user() I noticed too that when I do console.log inside a Tracker.autorun() the code inside it gets fired, so I assume that anything inside Tracker.autorun() gets fired on initial app load even though you didn’t do anything, is that correct?

Another related question for Store, I have a multiple Lists Component that are basically filled up by a publication; List of Products, Orders, etc. And these are paginated list and I keep the state on the Redux Store. Do you think it’s a good idea to keep the list of Records as well? Or would this be too much for saving into the Store?

Indeed, everything inside a Tracker.autorun gets fired at least once time.

I do also keep my collection inside a store. Persisting them is the way to go for offline fist apps. Unlike Meteor.user() which is a single item, there’s a downside into doing so. When the publication is ready, MiniMongo is flushed out and filled chunk by chunk with data received by DDP. Thus, unless you setup an observe mechanism (via observe or observeChange) to sync your store along the way with the changes you’ll get, your lists will get emptied and filled again leading to massive client side calculations on the main thread. On mobile (especially iOS), it can crash the browser. With careful design this can be avoided. This side effect handling is really a tricky part.

If you come up with a good solution, that would be nice to share it.

1 Like

Wow thanks @pierreeric especially for explaining things behind the magic of DDP and MiniMongo.

Are you referring to the Redux Store here? If so, aren’t the Reducers only mutate the State so it doesn’t overwrite the old one which means it’s faster since it doesn’t recreate from scratch, correct me if I’m wrong. Or are you saying the “recreation” itself causes the client side “recalculation” which makes the main thread busy?

Definitely!

Yes, by lists, I was speaking of lists inside the Redux store.

Indeed, reducers should only mutate data that have changed. This provides the capability to only recalculate React’s PureComponent (or any equivalent created via recompose or react-addons-shallow-compare) on which data have changed. Hence, in your reducers, only the reference to item from MiniMongo that have been modified should be updated, not the complete state of the reducer (assuming that like me, you’re using one reducer per collection).

1 Like