Allez, tant pis, on saute l'intro et on entre directement dans le vif du sujet (on n'a pas que ça à foutre, après tout).
Il était une fois un gros site web que s'apelorio Facebook. Qui dit Facebook, dit webapp plus grosse que la plus grosse de tes copines (no offense 1) ; et du coup, propension à se retrouver submergé de bugs plus élevée.
Les ingénieurs front-end de Facebook, confrontés à une codebase de plus en plus bordélique (personne ne voulant toucher certaines parties de celle-ci) ont dû repenser la structure des composants les plus cruciaux.
Face à ce besoin, ces développeurs sont donc parvenus à deux solutions :
Flux n'est pas un framework, mais simplement une architecture, une sorte de guideline qui résout pas mal de problèmes ayant pu apparaître avec les divers bibliothèques et frameworks MV* apparus lors des dernières années.
Flux comporte 4 concepts :
EventEmitter global ;model de l'architecture MVC, ils
contiennent les données, et réagissent aux actions que le dispatcher leur
transmet ;Jusque-là, rien de bien fou. C'est dans leur manière d'interagir que la particularité se dessine :
 
  En effet, le flux en question est unidirectionnel. Pour faire simple, on procède ainsi :
On définit une action via un action creator (on passera toujours par ces action-creators pour signaler une action) :
// actions/BasketActions.js
var AppDispatcher = require("../AppDispacher");
/*
  On garde un dictionnaire des types d'actions
  afin d'avoir un fichier donnant une vision
  globale de toutes les interactions de l'app.
 */
var ActionTypes = require("../constants").ActionTypes;
module.exports = {
  addToBasket: function(productId) {
    AppDispatcher.handleViewAction({
      type: ActionTypes.ADD_TO_BASKET,
      productId: productId,
    });
  },
};
On lancera par la suite cette action lorsque l'utilisateur aura cliqué sur un certain bouton, dans la vue concernée.
// components/Product.jsx
var React = require("react/addons");
var BasketActions = require("../actions/BasketActions");
var Button = require("./common/Button.jsx");
var Product = React.createClass({
  addToBasket: function(productId) {
    BasketActions.addToBasket(productId);
  },
  render: function() {
    return (
      <div className="Product">
        {/* rest of the component*/}
        <Button
          onClick={this.addToBasket.bind(this.props.productId)}
          label="Add to basket"
        />
      </div>
    );
  },
});
module.exports = Product;
Dès lors, à chaque clic sur le bouton en question, l'action ADD_TO_BASKET sera
passée au dispatcher, qui le signalera aux stores.
// stores/BasketStore.js
var AppDispatcher = require("../AppDispatcher");
var ActionTypes = require("../constants").ActionTypes;
var API = require("../api");
var merge = require("../utils/merge");
var Store = require("../utils/store");
var _store = {
  products: [],
};
var BasketStore = merge(Store, {
  /*
    Ici, on `register` un callback sur l'AppDispatcher,
    ce qui signifie qu'on verra passer toutes les actions
    de l'app.
   */
  dispatchToken: AppDispatcher.register(function(payload) {
    var action = payload.action;
    switch (action.type) {
      case ActionTypes.ADD_TO_BASKET:
        /*
             L'API va ajouter le produit et lancer une
             action `BASKET_UPDATED` dès que le serveur a répondu.
          */
        API.addToBasket(action.productId);
        break;
      case ActionTypes.BASKET_UPDATED:
        /*
            L'API a répondu, on peut stocker la réponse
            et signaler le changement
            aux vues récupérant ces données.
          */
        _store = action.reponse;
        BasketStore.emitChange();
        break;
      default:
        break;
    }
  }),
});
module.exports = BasketStore;
La vue, quant à elle, sera notifiée du changement, et effectuera un render() :
// components/Basket.jsx
var React = require("react/addons");
var BasketActions = require("../actions/BasketActions");
var BasketStore = require("../stores/BasketStore");
function getState() {
  return BasketStore.getStore();
}
var Product = React.createClass({
  getInitialState: function() {
    return getState();
  },
  _onStoreChange: function() {
    /*
      À chaque changement du store, on update naïvement
      le component et on laisse le virtual DOM faire son job.
    */
    this.setState(getState());
  },
  componentDidMount: function() {
    /*
      On écoute le store uniquement lorsque le
      component est monté.
     */
    BasketStore.addChangeListener(this._onStoreChange);
  },
  componentWillUnmount: function() {
    /*
      Et on arrête d'écouter quand il ne l'est plus.
     */
    BasketStore.removeChangeListener(this._onStoreChange);
  },
  render: function() {
    return (
      <div className="Basket">
        <div className="Basket-count">
          {this.state.products.length + " products"}
        </div>
        {/* rest of the component */}
      </div>
    );
  },
});
module.exports = Product;
Tout cela peut sembler relativement verbeux, mais il faut préciser deux choses :
StoreMixin simplifier la déclaration des
class React ;Si React et Flux vont si bien ensemble, c'est que l'approche de rendu "naïf" de
React (comprendre "React s'en fout de ce qui change, il appelle render à
chaque changement") permet de réduire la logique à écrire dans les Stores, et
donc de simplifier très fortement la codebase de l'app.
Lorsque qu'un ou plusieurs stores composent l'état d'un state React, alors à
chaque changement de l'un de ces stores, tous les composants React concernés et
leurs enfants vont appeler leur méthode render(). Afin d'éviter des appels
superflus à ces méthodes, React donne la possibilité de tester soi-même s'il est
nécessaire de mettre à jour le component en déclarant une méthode
shouldComponentUpdate retournant un boolean qui stipulera si oui ou non il
est nécessaire d'appeler render().
Bisous bisous.

Pour aller un peu plus loin :