From AngularJS to Flux - The React Way

pilau picture pilau · Dec 3, 2014 · Viewed 8.2k times · Source

As a developer with good hands-on AngularJS experience, how do I adjust my mental model of writing web apps in Flux using React?

I'm not looking for a Flux+React vs Angular answer (already plenty of that online), but I would like to know what are the biggest differences in the two "mindsets": beforehand, I was introduced into The Angular Way; comparatively, what is The React Way ?

As I leave the Angular universe and transition to Flux, what are the key things I need to start paying attention to?

Differences first, and now similarities: AngularJS is very opinionated and had some very big no-no's, like - don't put UI/DOM code in controllers. What are the big no-no's and opinions of React?

Last but not least, Facebook refers to Flux as an alternative to MVC, but as I am looking at it - React is the view engine, stores are model containers focused on a single domain, and the dispatcher and actions form a controller. So isn't this actually MVC with a different name?

Answer

fisherwebdev picture fisherwebdev · Dec 3, 2014

I'll let others do the compare/contrast with Angular, but here are some answers to two of your questions.

So isn't this actually MVC with a different name?

The presence in Flux of a separation of concerns between the data/logic layer and the view layer does not make it MVC. Many other patterns have a similar split, most notably CQRS, arguably Flux's closest cousin. There is no controller in Flux, in the MVC sense. The Actions and Dispatcher do not amount to a controller. The Controller-views are close, but are actually quite limited in their controller-like aspect. A key difference is that MVC controllers contain application logic and act upon models. Flux stores, by contrast, contain all the application logic and have no setters.

As I leave the Angular universe and transition to Flux, what are the key things I need to start paying attention to?

Key values of Flux:

  • Simplicity over complexity.
  • The mental model of the programmer is at least as important as the code itself.
  • Parts of the application should be highly decoupled and "know" as little about the other parts as possible.
  • Inversion of control: all control should reside in the stores, where state is managed. Stores are not acted upon, but rather informed by actions.
  • Applications should stay resilient and flexible as they grow, allowing for new, unexpected features to be developed more quickly and easily.

Key concepts in Flux:

  • Unidirectional data flow: Action → Dispatcher → Stores → Views
    • Every change in state and all new data begins with a dispatched Action.
    • This four-step data flow is the core mental model for the Flux programmer.
  • A dispatch causes an application-wide transformation of application state.
    • This is a moment in time, creating a snapshot of change. This is easy to reason about.
    • We cannot dispatch while dispatching and preserve this simplicity. Thus, any corollary change must be driven by the original action.
  • Flux stores are domain models, not ORM models. They contain all logic and manage all state for a particular logical domain within the application. They may contain collections, singular values or a combination of both.
  • Flux assumes that derived data -- where one store depends on changes in another store -- is an eventuality in complex applications where models or stores manage normalized data. To deal with this, a Flux Dispatcher should expose a mechanism to declaratively manage this dependency within the store. In Facebook's Dispatcher, this is done with the waitFor() method. This allows one store to wait for another store's response to an action before moving forward with its own response.

Primary parts of a Flux application:

  • Actions: an object literal containing new data and a specific type, allowing Stores to discern whether it is relevant to their domain.
  • Dispatcher: a registry of callbacks that, by way of the callbacks, distributes a payload (an Action) to the registrants (the Stores). It has no intelligence of its own. All intelligence is in the Stores.
  • Stores: a domain model which registers itself with the Dispatcher and emits a 'change' event whenever a change in its state occurs.
  • Controller-views: view components near the root of the component tree. They listen for 'change' events in stores and respond to this event by retrieving new data through the store's exposed getter methods and passing it to their children. The only difference between Controller-views and Views is this listening functionality.
  • Views: stateless children of the controller-view components, receiving and passing along data, much like pure functions. Views and Controller-views are most often implemented with React, as it provides the ability to re-render at will with very little performance loss.
  • Utils: libraries of pure functions that can be easily shared across different modules.

Overview, in depth: http://facebook.github.io/flux/docs/overview.html

Tutorial: http://facebook.github.io/flux/docs/todo-list.html

Examples: https://github.com/facebook/flux/tree/master/examples

Actions and the Dispatcher: http://facebook.github.io/react/blog/2014/07/30/flux-actions-and-the-dispatcher.html

Testing: http://facebook.github.io/react/blog/2014/09/24/testing-flux-applications.html

More out in the wild: http://facebook.github.io/react/blog/2014/10/17/community-roundup-23.html