An overview of Flux Architecture
Unidirectional (as opposed to bidirectional) data flow can be thought of as both a solution for mitigating the downsides of an event-oriented MV* system in which events fly uncontrolled in all directions and a technique that provides proper support to ensure architectural separation between concerns. Flux is also about reactive programming and the capability of one system to inject additional behavior without having to add more conditional logic to its core – think of a portal application that acts like a pluggable system. Nevertheless, immutability plays an equally important role in this picture and should be always considered when working with Flux and React.
With popular MV* libraries today, views manipulate state, controllers manipulate state and models manipulate state. The difficult part in this case is to actually keep in sync all these states with the DOM and vice versa, especially when dealing with asynchronicity. Often times you’ll struggle with a combination of imperative DOM manipulation and templating code that will run because something directly or indirectly caused it.
Just think of the complexity of the mental model that you’ll have to deal with when working with a scenario that looks like this:
This is when Flux becomes handy:
Although the MV* and Flux diagrams might seem similar at a first look, there’s one key difference between them: in the Flux diagram the arrows point in a single direction closing the loop in a consistent cycle – so is not a matter of being simpler than MV*, but rather being less confusing and easier to read.
Flux consists of four major parts: the Dispatcher, the Action, the Store and the View (React component).
The flow goes like this: an user interaction (mouse click) or an external event (push notification) triggers an action which is dispatched by the central dispatcher to all the possible stores, which in turn notifies all the interested views that a change happened in the state. This goes especially well with React’s declarative programming style that simplifies the management of state transitioning inside the views.
The actions flow through the system one at a time, the Stores becomes the single source of truth in the application and the Dispatcher allows you to specify the order in which the Stores execute their logic. Flux also separates the concerns of receiving and sending data. All these small things contribute to the overall predictability of the system.
Who said that diversity isn’t good? Is Model-View-Controller, Model-View-Presenter, Model-View-ViewModel, Model-View-Adapter, Presentation-Model and all their various implementation sounds familiar to you? Well, the same kind of thing happens with Flux: there’s a lot of libraries out there (Alt, Reflux, Fluxxor, Fluxible, Redux etc.) and a lot of nice features to choose from, but before commiting to any of these be sure to get yourself familiar with Facebook’s reference implementation https://github.com/facebook/flux/tree/master/examples as a starting point.
Flux can be seen as an alternative to MV*, since it „eschews MV* in favour of a unidirectional data flow”. However, Flux is not meant to be simpler than MV*, but rather was designed to keep your code clean and predictable. The versatility of this architecture is well recognized by many, including Twitter, Yahoo, Facebook, Instagram, Aurelia etc. Use it whenever your application targets a medium to complex codebase.