
Facebook Flux – Application Architecture for Building User Interfaces - diggan
https://github.com/facebook/flux
======
jefftchan
It's great to see Facebook releasing code for Flux. Hope to see more in the
future. Here are some other implementations of Flux for anyone who's
interested:
[https://github.com/BinaryMuse/fluxxor](https://github.com/BinaryMuse/fluxxor)
[https://github.com/jmreidy/fluxy](https://github.com/jmreidy/fluxy)
[https://github.com/yahoo/flux-example](https://github.com/yahoo/flux-example)

We recently adopted this architecture for a medium-scale project. The
unidirectional data flow has greatly reduced code complexity for us. We're
still not satisfied with our server syncing strategy. Seems like actions are
the best place to sync data, but how do you deal with interdependent actions?

~~~
jmreidy
I'm the author of Fluxy and would be happy to answer any questions here. The
big benefits of Fluxy vs other Flux approaches is that 1) Stores are built on
top of immutable data structures (via ClojureScript / mori) 2) Server side
rendering is baked in (or will be as of 0.4)

I'd also mention
[https://github.com/spoike/reflux](https://github.com/spoike/reflux) as an
implementation.

~~~
xiaoma
I've been reading about ClojureScript/OM and mori. What example apps are
online using either of them? This is what I've found so far.

ClojureScrpt/OM:

[https://github.com/swannodette/om](https://github.com/swannodette/om)
(several examples linked)

[http://rigsomelight.com/2014/05/01/interactive-
programming-f...](http://rigsomelight.com/2014/05/01/interactive-programming-
flappy-bird-clojurescript.html) (flappy bird clone)

React+Mori:

???

~~~
jmreidy
Fluxy has an example of using React + Mori - although it's still a work in
progress as Fluxy is developed.

[https://github.com/jmreidy/fluxy/tree/master/examples/todomv...](https://github.com/jmreidy/fluxy/tree/master/examples/todomvc-
flux)

------
xtrumanx
I'm still somewhat unclear on the point of the Dispatcher and Actions and they
simply feel like needless indirection to me.

For instance, in the flux-chat app within the linked repo, the MessageComposer
component calls `ChatMessageActionCreators.createMessage(text);` when the user
press the enter key to submit a message.

To find out how that ends up affecting the application, you need to jump
around more than a couple of directories to find out how it's all wired up.

I just cut out the middlemen and directly interfaced my Stores from my
components. My Store then emits a change event as usual and other components
that are subscribed to the change event than refetch their state. That part of
Flux makes perfect sense to me. The need for Dispatchers and Actions don't.

To be fair, I didn't start looking into Flux until my app starting growing
large enough that I started feeling the pain of my lack of architecture. The
Stores and the event emitter solved my immediate problems. Perhaps if my app
grows even larger, the Dispatcher may come in handy.

~~~
e1g
You are absolutely right that actions are just another level of abstraction
that come with their own pain, and if the pain they bring does not relieve an
even greater pain of not having them then there is no reason to introduce them
yet.

In our app, we started feeling the growing pain of a laissez faire approach to
internal comms. For us, a user interaction can generate multiple logical state
changes in the app, and several related interactions can cause
similar/identical changes to take place. So for us, "User Interaction->App
Change" is a many-to-many relationship, and Actions help us to wire them
together really well. Couple examples -

1\. Opening a modal with the detail view of the item. This can happen in
several ways (a user click, onload, keyboard shortcut, app event), and it
involves multiple steps (ui cleanup, fetching of more info, etc). Having an
actions allow us to guarantee that when we want X to happen in the app, all
necessary steps will be taken regardless of what causes X or in how many
places.

2\. Capturing analytics. We log all key interactions for internal analysis,
and some events simply do not belong in the store/ViewController/component, so
we capture in within the relevant Action. Low-level events are captured within
components (e.g. did they press the 'save' button or hit enter), while others
are app-level actions (e.g. 'view details') and are captured within Actions.
Bonus - as per the point #1 for us multiple user interactions can cause
similar app changes, but by also capturing the event within Actions we can
easily track all triggers - e.g. was the 'view details' caused by a clicking
on a link, using a shortcut, or another app-level change.

3\. Refactoring. Most of the app UI is aware of only two things - Actions and
(to a lesser extent) getState() of relevant stores. This means that as long as
we keep the public interfaces of those two unchanged, we can refactor or even
change the implementation as much as we need. Just last week we swapped the
inhouse filtering/sorting implementation a for new one based on Crossfilter
which caused a comprehensive rejigging of the stores' behaviours and methods,
and because we kept the same public contract it had zero impact on the UI
(besides a noticeable speed improvement).

Pardon the flawed comparison, but for us actions are useful in a similar way
that interfaces or MVC controllers are useful - as long as you keep them
lightweight and semantic, they provide predictable and reliable endpoints for
the app regardless of what turmoil happens behind the scenes.

~~~
couchand
I'd be very interested in seeing some Crossfilter-based filtering store code.
I've been working on a business application that needs to do quite a bit of
filtering and hierarchical rollups, and I'd really like to start using
Crossfilter for it so we can chuck the much more limited tool I whipped up
when we started the project and get that speed boost you mention.

We're also starting to see a lot of the many-to-many relationships in actions
you mentioned, which convinces me we need to work towards more of a Flux
architecture (it wasn't out yet when we started this lo those many months
ago).

~~~
e1g
I'd be happy to have a chat over Skype and share what we've done - just drop
me a line to [redacted]

------
driverdan
I previously spent time reading about Flux, watching the videos, looking at
Flux libs like Fluxxor and it seems overly and unnecessarily complicated to
me. The actions layer specifically seems unnecessary as it could be
implemented at the Store / model layer. The dispatcher is an event queue
system with support for dependencies.

To me it makes a lot more sense for React components to push an event directly
onto a pubsub event queue which then dispatches accordingly. When data changes
anywhere it fires an event that then passes new state to the top level React
component. Most of the actions you do to data are boilerplate and can be
greatly simplified from Flux.

What am I missing? Why is it so complex?

~~~
lebek
Seems like actions were designed to encapsulate update logic that doesn't
belong in the store (e.g. update ordering when multiple stores are involved).
A pubsub event queue wouldn't make this very easy.

------
fisherwebdev
The Dispatcher is not an event queue system, but rather a registry of
callbacks. This is a significant difference. The callbacks may be invoked in a
specific order, synchronously, so that dependencies between Stores are managed
effectively. Stores declare their own dependencies -- the Dispatcher knows
nothing of the internals of Stores -- through the use of the dispatcher's
waitFor() method.

Yes, you don't absolutely need the ActionCreator helper methods. You could
call AppDispatcher.handleViewAction() or even AppDispatcher.dispatch()
directly in the View. But keeping these things separated out keeps the code
nicely organized and keeps application logic out of the View. Additionally, I
find it helps to maintain a mental model where the only way into the data flow
is through the creation of an action, codified in the library of
ActionCreators.

------
neves
It has a fine explanation of the pattern:
[http://facebook.github.io/react/docs/flux-
overview.html](http://facebook.github.io/react/docs/flux-overview.html) but
what isthe reasoning in using this architecture? Or in pattern speak, what are
the forces that this pattern is considering? I can't find a clear explanation
about which problems is it trying to solve.

~~~
tracker1
In larger web based applications, tracking down side effects becomes
increasingly difficult with patterns that implement two-way data binding
(observables) or ad-hoc injection. This also in part takes into account part
of why React renders the way it does. With the flux pattern(s) along with
React's rendering pipelines, you can have heavy data flows, with minimal side
effects and a slightly easier time in terms of tracing the flow of data.

------
joelhooks
We've got a React Flux series[1] on egghead.io if you like video lessons.

\--

[1] [https://egghead.io/series/react-flux-
architecture](https://egghead.io/series/react-flux-architecture)

------
rubiquity
I've been using React quite a bit but haven't had a need for Flux. Using React
to implement all of my UI concerns, combined with Backbone for easy to use
persistence and modeling, has worked wonderfully for me. YMMV :)

~~~
rjn945
I agree. The combination of Backbone models/collections and React views bound
together by React.Backbone[1] so that the views automatically re-render after
any changes to the models/collections has made the data-heavy application I'm
working on surprisingly easy to develop.

The real issue I've been having React -- that I'd I like to see dealt with by
a library/design pattern -- is dealing with transitions between view states.
Re-rendering the view on any data change can result in very abrupt changes.
For instance, my app displays multiple lists of items. When the user edits an
item, that can result in the item suddenly disappearing from underneath their
cursor to reappear somewhere else in that list, in a different list, or
nowhere within view.

I've been able to handle each issue of this nature as it arises in an ad-hoc
fashion, but I'd really like a more formalized way in React to say, "when
attribute X changes, use transition Y to change from the old view state to the
new one".

Does anyone know of an existing solution to this problem?

[1]
[https://github.com/usepropeller/react.backbone](https://github.com/usepropeller/react.backbone)

~~~
imjared
Check this out: [https://github.com/andreypopp/react-router-page-
transition](https://github.com/andreypopp/react-router-page-transition)

Not simply react but you can get the idea.

------
voyou
A lot of this seems like it's just MVC, except what they call the "View" is a
traditional MVC Controller (the UI element that handles user interactions and
sends these to the Model), what they call the "Controller-View" is a
traditional MVC View (something that gets notified when the Model changes and
displays that change to the user), and what they call the Dispatcher is what
traditional MVC calls the Model.

They write "Flux eschews MVC in favor of a unidirectional data flow", but MVC
already _has_ a unidirectional data flow (Controller -> Model -> View). Is
this just a case of those who don't understand MVC are compelled to reinvent
it?

EDIT: Actually, the main addition over MVC seems to be that the Stores
declaratively specify their relationships between one another (which are then
resolved by the dispatcher), rather than the developer writing a specific
Model implementation that explicitly orders the changes to related elements of
the model. I'm a bit suspicious that this would be less explicit, and so
harder to maintain, but maybe I'm wrong.

~~~
augustl
The main difference between Flux and MVC is the unidirectional data flow. In
MVC, a controller updates a model which updates a view which again talks
directly to a model that might invoke another view which again might cause a
model update, and so on. In Flux, the only thing a view can do is to invoke
actions on the top-level dispatcher. Furthermore, views are never partially
updated, they are always re-rendered from scratch every time (like you
typically do in the back-end).

~~~
voyou
But as I said, MVC already has unidirectional data flow. An MVC View doesn't
make changes to the Model, so can't lead to cascading updates of other Views.

------
sehr
Actual site for the project:

[http://facebook.github.io/flux/](http://facebook.github.io/flux/)

Seems to still be in flux.

------
hcarvalhoalves
It's easy to integrate with Backbone if you want for this kind of
architecture, as it already implements events and stores. I've found it
requires _less_ boilerplate than the example in the repo.

~~~
markplindsay
I just wrapped up the initial version of a medium-size app using React. It was
my first use of the library in production.

I had originally used Backbone.Model and Backbone.Collection in conjunction
with React. But after reading about Flux on the React blog and watching the
video explanation back in May, it only took me a week to replace all of my
Backbone models and collections with Flux singleton-stores. Coupled with
Andrey Popp's react-router-component[0] (now replaced by rrouter[1], I
think?), I was able to remove Backbone from the project entirely.

I think that Flux is more flexible than Backbone. I really like the ability
for a store to take on characteristics of both models and collections. It is
also easy to combine many different external resources to compose the "one
true source" of a particular type of data for many different components. I
don't feel any particular need to bring back a Backbone dependency in future
React projects.

[0] [https://github.com/andreypopp/react-router-
component](https://github.com/andreypopp/react-router-component)

[1]
[https://github.com/andreypopp/rrouter](https://github.com/andreypopp/rrouter)

~~~
xtrumanx
First it was react-app-controller which was deprecated in favor of react-
router-component which is now being deprecated in favor of rrouter.

At least Andrey add his reasoning for the latest deprecation in rrouter's
documentation. Although the page regarding server-side regarding in the
rrouter docs is empty :(

According to the docs "RRouter was developed to replace react-router-component
and fix design flaws introduced by it." Maybe I'm just unfamiliar with the npm
community but is it typical to just rename projects once they introduce
breaking changes?

------
colinhowe
We've been playing with this architecture. It makes testing a lot easier - you
just shove data in where needed and things pop out the other end. It also
forces us into splitting things up in a more sensible manner. Along with
easier testing is easier reasoning.

That said, like most new architectures/frameworks finding a big example (not
just a TODO app) is really hard. We are currently prototyping a big app using
React/Flux and we find ourselves having to question ourselves a lot more than
we'd like.

~~~
state
Is there any chance your code is public?

------
api
FB seems to be doing some amazing work trying to make the web a more tolerable
UI platform.

Once we finally have a good, solid, stable UI building consensus in HTML5/JS,
it'll not only be possible to use it for the web but for the desktop too via
node-webkit / atom-core.

------
fiatjaf
How does this compare with FRP?

I've been thinking about this and concluding that React wouldn't benefit even
a little from those FRP libraries and architecture, it is already quite
functional reactive. Am I wrong?

~~~
lightblade
React is not functional reactive by itself. Although there's no stopping
people from integrating it with other FRP libraries.

~~~
fiatjaf
Well, I know that.

------
fnordsensei
This looks very interesting, and if I'm not mistaken, slightly reminiscent of
how apps are built with Om (using core.async for dispatch and atoms for
storage).

------
joekrill
Excellent! Been waiting to see an "official" implementation of this. There's a
lot of different information floating around about how Flux architecture
"should be done", but I've been waiting anxiously to see how Facebook actually
implements it/suggests it be implemented.

------
kitd
So, does this make stores 'Flux capacitors'? (pretty pls)

~~~
wildpeaks
Already tried, but they wouldn't go for it :)
[https://github.com/facebook/react/issues/1811](https://github.com/facebook/react/issues/1811)

------
igorgue
I know is stylized as "f.lux" but fuck man...

Why does big companies do that? Just recently Apple's Swift and now Facebook's
Flux.

~~~
notduncansmith
Flux (stylized "f.lux") refers to the awesome screen dimming/coloring
software: [https://justgetflux.com/](https://justgetflux.com/) Completely
unrelated, but I highly recommend it for anyone who stares at a screen for a
living.

