Flux: How to Implement A Basic Application (or, Flux for Dummies)

Two weeks ago we began our thesis projects at Hack Reactor - I’m working with a great team on a platform for holding elections - and that meant deciding what to do with our last few weeks of education before hitting the job market. We decided that we wanted to maximize the number of technologies we could learn on this project, so it’s really a canvas for exposing us to as much new material as possible. Looking at all the options ahead of us, one stuck out for everyone in the group: Facebook’s forward-thinking frameworks React & Flux.

I owe many thanks to HR23 alum Preston Parry for his Curriculum for Learning React & Flux; it was a great way to get started. But while I finished that with a great understanding of React, I still didn't quite understand the actual mechanics of how to use the Flux workflow, even after working through Facebook's somewhat lacking Todo-MVC tutorial. So, to help those who come after me, here's a quick primer that will get you up and running with Flux as fast as possible.

First, this assumes that you're familiar with the basic concepts behind Flux (unidirectional data flow to help maintain consistent state), and that you're using React for your views. You can get up to speed quickly here.

Flux Data Flow Diagram

The Dispatcher

The Dispatcher is key to Flux - but it's not where you spend most of your time. In fact, we're using the reference implementation:

var Dispatcher = require('flux').Dispatcher;
module.exports = new Dispatcher();

In a simple application, the Dispatcher really just accepts actions and passes them through to the store. More complex applications may use the waitFor() feature, but that's not necessary if there isn't the potential for conflicting updates.

The Stores

This is where the action really happens. It took some careful thought to figure out why the code was organized the way it is in Facebook's TodoStore example. Here's what I figured out:

  • The first interesting bit is the private _todos variable - this is where you keep your application state. I'm actually using a few private variables in the application I'm building. Go wild, but just remember that you shouldn't be directly accessing them.
  • Directly below that are a number of named functions. These are the functions that modify your private variable data. If you need to change something, you'll be using them - but by keeping them out of the TodoStore object, you remove the possibility of accessing them directly from your views.
  • Next is the TodoStore object that you'll require() in your views. These are the getter functions (i.e. Backbone's get()) that allow you to access, but not modify, your data. There are two other functions here that allow you to register listeners with your views. addChangeListener() and removeChangeListener() are generally called in your React componentDidMount() and componentWillUnmount() methods, and let you tell your views to update when the Stores change (generally through a this.setState() call).
  • Finally, the Dispatcher registration. This allows you to register all the potential action callbacks with your Dispatcher - generally, there should be one of these for each of the named functions at the top; it's how you'll invoke them.

The Constants

This one is simple: for every action you need to dispatch, set up a constant. This lets you keep consistency between files and lets you avoid tracking down many strings if you need to change something.

The Actions

You'll require() this into your views as well, and call its methods when you want to update any data in the stores. Each method corresponds to one of the named functions in the Store (which corresponds to a constant). The general format is that you invoke the dispatch() method on your Dispatcher, with a payload object in this format:

{actionType: CONSTANT, //what function you want to trigger
parameter1: ,
parameter2: }// the paramters you need to run the function

For instance, if you're creating a todo item, you'd include its text. If you're deleting one, you'd need its ID number.

Putting it Together

It comes together in the views. You require() the Actions and Stores, using the Action methods as you would a Backbone set() and the Store methods as you would a Backbone get().

And that's it! Data is flowing in one direction through your application, ensuring consistency. It may seem like a lot to wrap your head around, but once it clicks, Flux is a powerful tool to develop complex applications.

Bradley Portnoy

Bradley Portnoy

I'm a recovering politico and brand marketer diving head-first into the world of software development, and always searching for ways to impact the world for the better.

View Comments