A year ago, it was really hard to move away from writing Flux components in pure vanilla Javascript. The reason? there was a lot of Flux implementations (libraries) out there, but all of them were too young to be trusted in a production environment.
Within the last couple of months, Engineers at Facebook; the creators of Flux, have publicly endorsed one library: Redux, as well as their own Flux library, which includes new store classes that you can extend in order to implement your own ones without the boilerplate caused by Flux implementations written in vanilla Javascript.
So, which one to use? Well, it depends. Redux will require quite a refactor of your current flux application, specially if you already have several stores in place. This is because Redux advocates for having only one master store, instead of several ones. Also, The classic Flux dispatcher is now gone in Redux, and you will need to digest new concepts such as Reducers (for handling actions) and Middleware (for async API calls).
However, Redux has a well documented migration path, which comes down to this:
- Create a function called createFluxStore(reducer) that creates a Flux store compatible with your existing app from a reducer function.
- This allows you to gradually rewrite every Flux Store in your app as a reducer, but still export createFluxStore(reducer) so the rest of your app is not aware that this is happening and sees the Flux stores.
- As you rewrite your Stores, you will find that you need to avoid certain Flux patterns (or anti-patterns?) such as fetching API inside the Store, or triggering actions inside the Stores.
- When you have ported all of your Flux Stores to be implemented on top of reducers, you can replace the Flux library with a single Redux store, and combine those reducers you already have into one using combineReducers(reducers).
- Then you will need to port your views to use react-redux or equivalent.
- Finally, you might want to begin using some Redux idioms like middleware to further simplify your asynchronous code.
The alternative to Redux would be to use Facebook’s flux-utils which is part of flux-2.1.0 (or newer). This is simply a set of basic utility classes to help get you started with Flux.
Just like Redux, Flux Utils allows you to reduce boilerplate, but without the need of a dramatic application refactoring. You can simply extend one of the stores that they provide which will save you a lot of time when writing new stores and will make your existing ones more maintainable.
As an example, here is my attempt to migrate the current Facebook’s TodoMVC example to use Flux utils, note the amount of boilerplate that gets removed, while keeping the classic Flux architecture:
And to simplify things even further, I also added the use of my own extend-it library, which will save you a few lines of code when doing classical inheritance in ES5:
So, Flux or Redux? If you want to reduce boiler plate and improve rapid development for an existing Flux application that already has several stores, I would recommend refactoring your stores to extend from the stores provided by Flux Utils.
However, if you are starting to develop a Flux application from a scratch, or your current application doesn’t have that many stores then I think Redux would be the way to go, since it forces you to avoid anti-patterns, and at the same time it will help you to keep your code base simple and organized.
There is a third alternative: you can easily migrate your existing stores to use Flux utils, as the migration is pretty straight forward, so you can take advantage of the ‘boilerplate reduction’, and then start using Redux for new stores. Then gradually migrate the legacy stores to Redux as time permits. This way you get the benefits of both worlds, at least until you finish migrating all the stores to Redux.