“ReducEEEEERRRRRRRSSSS!”

Flux is a cool architecture, no doubt. It’s honestly very nice to explicitly say what’s changing and not rely on perfect documentation of all your $.trigger('bluh'); nonsense. And then when Redux came out, it was like “Ooook, Flux is better with immutibility.”

But as I began to use it more I started getting frustrated with a seemingly endless string of buzzwords: “store”, “dispatcher”, “reducer”, “combined reducers”. I was like, “dude, you mean a POJO with my UI State, basically a Pub/Sub module, and a function that simply tells my POJO to update.” I’m probably just stupid, but that’s how I understood those confusing word.

I actually got so confused and frustrated that I started building my own state-management library. I called it “SubState” cuz it’s a Pub/Sub module with some added frills (Flux frills).

Now, you (especially if you come from Vue) might be saying: “Pub/Sub or EventBus can get messy quickly. When too many components talk to each other you lose track of your dispatches and event types.” Fair enough.

Well, SubState can house all of those reducer-type methods (if you like), and it also houses all of your state and an events object with all of your event names. So you can simply inspect your SubState instance and see all of your logic. It can be the “single source of truth”

“I command the truth!”

SubState works like this:

const substateInstance= new SubState({state: {name: 'Tom', stupid: true}});

Then you have State, and a Pub/Sub pattern to use. And this Pub/Sub has an on an off and an emit method (I tried to keep it like jQuery-ish and NodeJS EventEmitter-ish — I thought it made more sense than “dispatcher”).

So now you can do:

substateInstance.on('SOME_EVENT', yourCallback);

And you can:

substateInstance.emit('SOME_EVENT', stateToChange);

And when you’re done with that event you can:

substateInstance.off('SOME_EVENT', yourCallback);

It’s a Pub/Sub… but it wires up the 2 “events” you have to care about:

STATE_UPDATED STATE_CHANGED

STATE_UPDATED means exactly that, the “whole state” was updated, or really, you want to receive the entire state when anything changes.

STATE_CHANGED : for some reason you did that “time travel” nonsense and went back a state or 2. So get the one you “time traveled” to. (BTW, ‘The Time Machine’ is an amazing novel, highly recommend).

Ok so, how do you actually update the state? You could update it directly, but that’s not “functional programming” blah blah. So there’s a handy event to emit within the substate instance itself:

substateInstance.emit('UPDATE_STATE', {name: 'Thomas'});

Wow. Now the STATE_UPDATED event will emit and return a brand new State like this: {name: 'Thomas', stupid: true}

What about those ridiculous switch statements in Redux reducers? Don’t worry, reader. I thought of it. You emit a $type property with your object.

substateInstance.emit('UPDATE_STATE', {$type: 'MY_CUSTOM_UPDATE', name: 'Thomas'});

Now you just listen for MY_CUSTOM_UPDATE and you can fire callbacks only when certain things change. So instead of handling every STATE_UPDATED your component can just listen for MY_CUSTOM_UPDATE and only repaint or recalculate then.