Flux Cargo-Culting

When Facebook presented Flux, the architecture they were using internally to develop applications (specially coupled with React), they didn’t provide a reference implementation — just the concept of how to architect applications around the flux ideas and the benefits from this approach. The Facebook’s Flux team did provide a small todo example with a self proclaimed “naive” implementation of a dispatcher, just for the sake of illustrating the concept, but it took some time for them to open source their reference dispatcher and more complete examples and documentation.

This is not a bad thing, as it helped convey the message that Flux is an idea, an architecture, and not a library, but because Flux immediately resonated with the community, lots of guides and tutorials as well as a profusion of libraries emerged in the meantime. And by the time Facebook open-sourced its reference dispatcher implementation, some misunderstandings and cargo-culting has spread. Things like:

  1. Helper methods:
    Helper methods can be really useful if you are using them consciously on your app. Blindly copying those methods from the examples only add to boilerplate.
  2. Overall modules structures:
    Facebook made the deliberate decision to keep Flux library minimum (for practical purposes, it only contains a dispatcher). This means you get to build Stores, Constants and Action creators as plain javascript objects. Beginners tend to copy these files structures from the Flux examples, and there’s nothing wrong with this, but it’s important to know you can shape them to better fit your app and taste. Some people, for example, get specially mad about the big switch statements inside a store dispatcher callback — but since it’s just plain javascript it’s easy to achieve similar results with different approaches.

In this small article i’d like to show some specific cases where cargo-cult usually appears and which are the alternatives:


The dispatcher

The very first Flux Todo Example had two helper methods on the dispatcher: handleViewAction and handleServerAction. Having helper methods on your app’s dispatcher can be helpful in some use cases, but are not obligatory. Your dispatcher can be as simple as:


Store’s change listeners

Components need to listen to Store’s changes in order to trigger the re-rendering of the UI. If your store extends EventEmitter, you don't need to create helper methods like addChangeListener and removeChangeListener: Simply use EventEmmiter’s addListener and RemoveListener directly on your components:

In your component, use the EventEmmiter’s addListener and removeListener directly.

UPDATE: Bear in mind, though, that exposing your store as an Event Emitter can potentially break the single direction data flow pattern (as it would be possible to emit events from anywhere).

In case you want more control about what can be done on a Store, do provide “addChangeListener” and “removeChangeListener” methods, but do not extend EventEmitter - Instead, create a local EventEmitter instance (that won’t be accessible outside the module) and use it on your Store.


Long switch statements

While I think switch statements are actually a good way to handle incoming actions in the store’s callback that was registered on the dispatcher, some people get really bogged about this.

Remember that a Store is simply a javascript module, not some crazy or restricted DSL: You can handle incoming actions in multiple ways.

For example, if you have an ES6 transpiler such as babel, you can use Computed property names to create an object whose keys are Actions Constants pointing to local functions:

Again, this only shows you can handle the Store’s dispatcher callback in different ways, but that’s not intrinsically better than a switch statement, for example.


Constants

Both examples provided with Flux have a “constants” folder. This can give the impression that you have to split your constants in many files, but generally you will want to keep them on a single file unless you're on a large project.
I really like the approach Ryan Florence used in some of his examples: Keep a single Constants module for all your application’s constants on the root javascript folder or under ‘utils’.