If Facebook’s Flux is the answer, what was the question?

In Flux, instead of storing your data once, in a simple object, you’re supposed to store several versions of it, in things called “stores”.

And instead of exposing methods on the stores, to allow the data to be modified directly, you’re suppose to trigger “actions” that your data stores are listening out for, so they can all update their contents accordingly. This is how they’re meant to stay in sync. In fact, if an application only had a single store, there would be no point whatever in using Flux.

Web apps need to minimise what they download and upload; they deal in snapshots of state; they don’t download a historical log of all actions previously performed and replay them. The only reason for dispatching actions within a web client app is so that multiple stores can stay in sync as data is updated.

However, if you take a look at Facebook’s own example code, you discover something odd. There’s an example called TodoMvc, and it only has one store. Nevertheless it diligently follows the pattern, despite there being no point to it. Fair enough — a simple example may not be totally representative.

Okay, let’s try the other example, Chat. This has three stores, which seems more hopeful at first glance. There is a store that holds a list of threads, and a store that holds a flat list of all the messages across all threads.

But the data in this app is hierarchical — threads own messages; the app never displays all messages across all threads — it only shows the messages for one thread at a time. So it would make a lot more sense for each thread to be an object that had its own list of messages. It would be trivially easy to manipulate it correctly to keep it consistent.

And then there’s the store that holds the count of unread threads. Except… it doesn’t store it at all. It recomputes it on the fly by iterating through the thread store. And why shouldn’t it? This is going to be a very fast operation even with ridiculous numbers of threads. The only problem is, this is rapidly turning into a single-store application, and therefore not a realistic use-case for Flux.

And the fact that Chat is a forced example is pretty significant, because according to the introductory presentation, Chat was the use case that prompted Facebook to introduce Flux in the first place.

There is a great, glaring irony to all this. Flux is intended to be used alongside React, which is purely a library for creating and composing together UI components. React takes a very simple approach to ensuring consistency: whenever something changes, the tree of UI components (the “virtual DOM”) that depends on it is recomputed from scratch by a pure function.

And what works for React’s virtual DOM works equally well for layers of data derived from other data. If all you have got stored is messages, each tagged with a thread it belongs to, you can compute the list of threads from them on the fly with a pure function. For the vast majority of applications, this will perform perfectly well. This is the whole point of React: JavaScript runtimes are blazingly fast these days.

In summary: Flux is not the ideal way to structure most web apps, including the kind of apps Facebook was trying to deal with when it came up with Flux.

You can find a more in-depth look at Flux on my blog.

Show your support

Clapping shows how much you appreciated Daniel Earwicker’s story.