React JS — WindowX state management (alternative to Redux/MobX)

Redux and MobX are both great. People can argue whether they prefer apples or oranges all they want. But on your next adventure, maybe its best to take a granola bar.

Here is an alternative. It is magically simple. But it is simply vanilla Javascript. There are some limitations. As with any system, there are pros/cons, and each system works best for a particular application/requirement. Redux and MobX are great for large and dynamic data structures. Redux is more suited to the larger and more complex. But MobX will manage almost everything that almost any organization throws at it. But both have a lot of overhead - a lot of code to maintain for every global variable. Every time you initiate or change a variable, there are some hoops to jump through. What if there was an easier way. What if there was a way to set global variables in React as easily as in a plain old Javascript + DOM webpage? You may say that I’m a dreamer - after all, there are scopes which limit your access to global variables. And, if you make all variables global, like “window.myVariable”, then you get a mess.

But what if…
1)
make one window variable: “window.store”
2) add your application-specific variables to that, like “window.store.notifications” or “window.store.alert”
3) then watch for changes in each React component which needs that variable, and run this.setState() on change, to re-render the component if necessary

Now you have a very basic global state management solution. Whenever “window.store.notifications” changes, the component which uses it re-renders. A benefit to this is that you can change your global app state from literally anywhere, with no overhead. Simply set the global variable, and it automagically updates where ever needed.

Problems?
4)
we need to ensure that each change to the global state conforms to its intended variable “type” and format
5) we may need to filter the new incoming value, as we do in Redux actions or reducers — can’t just accept whatever data some random part of the application sets
6) we may need to check the new value for security concerns

You say “Aha! this is not possible!” I say “It is not only possible, but easy - with Javascript’s built-in Proxy object”. The Proxy has been around a while, and it is what allows Redux and MobX to do their magic. It monitors a variable object for changes, and then is able to apply a set of filters and rules to that change. In this Proxy setup, you can perform type-checking, validation, filtering, and anything else - to one or all global state properties.

This alternative solution uses window.store and Javascript’s Proxy object. So, lets call it “WindowX”.

Sample code:
https://github.com/paulshorey/mui-form-example/blob/master/src/window/store.js

This does not replace Redux/MobX for all cases. Usually you need the extra benefits of a data framework, such as:
1) security — this proposed solution leaves your variables exposed
2) separate logic file for each store property or component
3) middleware, which is able to modify the incoming data based on server response
4) community plugins

But maybe sometimes you don’t. The benefits of this proposed solution are unparalleled simplicity:
1)
to initiate a state property, or set its logic and filtering, you do it in just one file: window.store.js
2) to change a property’s value, you simply set it, as with a normal javascript variable. No need to change any other files anywhere. It will go through the predefined validation and filtering and type checking, then be updated in every component that uses it.

Consider:

window.store.alert = {title: “Attention:”, body: <p>{error.message}</p>}
This can be called from literally anywhere. The Proxy filtering could then make sure that it is in the correct format, and even add “window.store.alert.opened = true/false”. Then, your higher-order-component will notice it changed, and setState on your component.

Just remember, don’t store any private data in this global window scope!

This is ONLY for PUBLIC data such as UI state!

To manage dynamic global data and keep it private, stick to Redux/MobX. To add data which will never change, use React Context.

Like what you read? Give Paul Shorey a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.