Redux. Concept over implementation
Case against Flux
Why didn’t I just stick with the standard one, why not just keep Flux? I found that while it delivers on the one-way flow it’s way less simple than advertised. Despite having many good concepts of Stores and Actions, the amount of code and understanding that needs to go in properly connecting them is just too much. Especially when multiplied and coupled with Dispatchers along with all other necessary steps and boilerplates to connect everything into a working structure.
Redux, in my opinion, uses some of these concepts but offers them in a much simpler way.
Its three main rules represent the three most important advantages it has. Not all of them are Redux-exclusive but combined they make a hell of a good solution.
Single source of truth
“Single source of truth” is telling us that the whole application has just one state tree. It’s probably the biggest pro for a couple of reasons. Firstly, imagine how easy it’s to hydrate it with data prepared on the backend. You send the app along with all of the initial information, without having to calculate all of that by the user’s browser, so they get instant access to everything.
Another thing is developing or debugging longer, more complex flows, e.g. adding an offer on a confidentials site. Usually it’s clicking a couple of buttons and entering few random strings of text everytime it crashes or after we write the logic for the next step. What most of us probably did before was adding some temporary logic that skips all of that to the right step. In Redux we can just populate the necessary part of the tree with proper data, because certain state equals the step the app should be in. This seems like entering a lot of data as well, but keep in mind that for Redux apps, with just a single state tree, we usually need to design the data structures early on, so we probably already have those mock ups somewhere to use.
I’ve mentioned that we need to have a well-thought-of data structure. For me it’s another important advantage. It forces a good architecture of the app, and all of its components need to be planned, along with how it should scale. It requires a level of understanding how to build proper flat data structure, which in turn makes it easier to manage new features. One notable helper library here is Normalzr. Not diving in the specifics, it allows to create a schema and given a nested object tree it outputs a nice, flat structure.
The second pillar of Redux is the immutability of the state. The only way to change its data is to dispatch an action that describes what happened in the app. This ensures that the flow of changes is not random, and can be easily traced.
The last rule is that most of Redux components use pure functions. Not only does it enhance code readability without having to follow multiple side-effects happening in ever-branching methods, but it also makes the testing significantly simpler. The only thing to do is to provide an input to a function and then to check if we have a desired output. Usually this prevents a situation where we need to mock a lot of complicated things to build a complete test environment.
I don’t want to elaborate on the different components that Redux is build of. It has truly one of the best documentations I’ve seen, and actually read, in years. It explains with some nice examples all of the things that are happening in the flow and provides some nice tips and good practices to keep in mind when creating your own apps. I will just show you how easy the complete flow is.
Whole thing starts with the dispatching of an action (which is a plain object) returned by an action creator. That action is describing for a reducer what happened, so it can prepare a new state accordingly. In the last step the new state is being saved by the store. One thing you can add to that is connecting some middlewares between the action creators and returning the action object itself to accomodate asynchronyous flow (like API requests, etc) or extend the app, e.g. to log every performed action, thus allowing everything that happens to be easily traced.
What draws me to Redux is that, in words of its creator, it’s not another derivate of Flux, but instead a project that’s inspired by it. It uses some concepts that are already introduced and accepted by the majority of the community (one-way flow, actions, immutability, etc.) and offers them in a simple package that you can use once you get to know just few basic rules.