How it started
We, at BlogVault, decided to completely redo our web application UI, which is currently powered by Backbone.js with Underscore templates. Exploring options, we tried using MarionetteJs on top of Backbone.js for our specialized migration dashboard that powers migration for our partner web-hosts like wpengine, savvii, cloudways etc. While MarionetteJs provided a decent improvement over our Backbone.js code with its common-practice architectural solutions, the code still looked hacky at times.
In Backbone.js responsive views listen to models and collections and re-render once underlying data is updated. However Backbone.js being so minimal (which is often credited as a plus point), it leaves most design completely on developers. This is where the problem starts, if you are not a disciplined coder there are enough ways to screw up. For example – manipulating DOM directly upon success callback. I have seen enough people posting such code on various forums. This may not be a big issue at beginning, but as the application keeps growing and you keep adding new features, you realize your views are not in perfect sync with your models and collections anymore. A quick fix would be manually manipulating DOM to update UI, which as insane as it sounds, is not at all a rare practice, such code snippets are posted all over the internet in abundance. This was just one example, there are many other. This leads to spaghetti data-flow, abrupt DOM manipulations, and at times massive memory leaks. This was one of the big reason we wanted to move away from Backbone.js.
Next we considered AngularJs, however dropped it almost immediately after we learned that Angular 2.0 (which at that time was not released and currently is in beta) won’t be backward compatible.
Finally we decided to try Facebook’s newly released view library React and application architecture Flux. Rewriting everything in React and Flux had its own risks. React was brand new, meaning considerably smaller community, lesser plugins and most terrifying – fewer StackOverflow posts! Also most of the code is in ECMA6, and to add further, Flux is a non-MVC (or MV*?) architecture. However experimenting with few examples we decided to give it a try.
What is React and Redux?
Redux can easily be distinguished with most of the object-oriented MV* architectures, as:
- the complete state of your application is maintained inside a single object called store.
- at any given time the App’s state (store) is immutable, and
- data flows strictly in one direction.
That’s a lot to digest if you are new to this. However the more we dive into the real world problems, more it makes sense.
How they work?
Data in a Flux architecture flows in single direction:
Action > Dispatcher > Store > View
Action suggests something just happened. Dispatcher is called and it sends the action to the store. Store modifies itself (without mutating existing structure) in response to action. Finally, as per the state of store, view gets updated.
Redux is an extremely light implementation of Flux architecture. It implements the above Flux data-flow in following sequence:
Action > Dispatch > Reducer > Store
In Redux implementation, an action is a plain object describing what happened. A function store.dispatch(action) is called to pass action to store. By this time, Redux knows something happened and depending on action, it has the result for what happened (suppose as action triggered a server request and got response). Now, in reducer we specify how the store’s state should change in response to that action. Once the reducer modifies the state, React picks up the new store and re-renders view automatically.
Now coming back to React. As it should be clear by now, React is the view part of our implementation. If I have to explain it in the vaguest possible way, I can say its comprises of two parts:
- a template written in jsx.
- a mechanism to maintain its own internal state in memory.
At the end React processes these two parts and churns out good-old-plain HTML that your browser understands.
Given the capability of maintaining states, it makes React extremely powerful and a delight to write UI on. Think of this – you need to display a message based on some event. Generally you will do DOM manipulation in event handler. However in React all you need to do is set a state in event handler and as per your template, React will automatically re-render that particular part. That’s powerful, and clean!
In fact I recently read somewhere someone comparing DOM manipulation with goto statements. Its as bad! There is no definitive source of truth and hence tracking down the source of manipulation is walking into hell-hole.
React and Redux together are fairly powerful and provides robust and efficient solution for building a single page application. In Redux, since the data-flow is restricted to one direction, scope for screwing up is significantly reduced. React has beautiful in-built data-binding which responds to state changes flawlessly. And lastly React provided various components lifecycle callbacks which helps write elegant easy-to-maintain code.