This page is not available in every language. Missing translations are disabled in the language selector.

Quick reference

Flux Architecture Cheatsheet

A quick reference guide for Facebook's Flux application architecture: Dispatcher, Actions, Stores, Views, waitFor execution ordering, and event bindings.

· Published

Flux is the application architecture developed by Facebook for building client-side web applications with unidirectional data flow.

Architecture Overview

  ┌───────────────┐
  │ Action Creator│ ───> Action ───┐
  └───────────────┘                │
                                   ▼
┌───────┐                      ┌────────────┐
│ View  │ <── Change Event ─── │   Store    │ <─── Dispatch(Action)
└───────┘                      └────────────┘
    │                               ▲
    └──────── Action Trigger ───────┘
  • Dispatcher: Single central hub that receives actions and broadcasts them to registered store callbacks.
  • Stores: Hold application state and business logic, updating state upon receiving dispatched actions.
  • Views: React components listening to store change events and requesting new actions through action creators.

Dispatcher

Registering and Dispatching

const { Dispatcher } = require('flux');
const AppDispatcher = new Dispatcher();

// Register a store callback; returns a token used for waitFor()
const token = AppDispatcher.register(function (payload) {
  switch (payload.actionType) {
    case 'TODO_CREATE':
      TodoStore.create(payload.text);
      TodoStore.emitChange();
      break;
  }
});

// Broadcast action payload to all stores
AppDispatcher.dispatch({
  actionType: 'TODO_CREATE',
  text: 'Learn Flux'
});

Sequencing Stores with waitFor()

const FlightStore = {
  dispatcherIndex: AppDispatcher.register(function (payload) {
    switch (payload.actionType) {
      case 'BUY_TICKET':
        // Ensure CityStore finishes updating before FlightStore runs
        AppDispatcher.waitFor([CityStore.dispatcherIndex]);
        FlightStore.country = CityStore.getCountry();
        break;
    }
  })
};

AppDispatcher.waitFor(tokens) pauses execution of the current callback until the callbacks corresponding to the specified tokens have run.

Stores

Plain Store Structure with EventEmitter

const EventEmitter = require('events').EventEmitter;
const AppDispatcher = require('../dispatcher/AppDispatcher');

const _todos = {};

function create(text) {
  const id = Date.now();
  _todos[id] = { id, text, complete: false };
}

const TodoStore = Object.assign({}, EventEmitter.prototype, {
  getAll: function () {
    return _todos;
  },

  emitChange: function () {
    this.emit('change');
  },

  addChangeListener: function (callback) {
    this.on('change', callback);
  },

  removeChangeListener: function (callback) {
    this.removeListener('change', callback);
  }
});

TodoStore.dispatchToken = AppDispatcher.register(function (action) {
  switch (action.type) {
    case 'TODO_CREATE':
      create(action.text);
      TodoStore.emitChange();
      break;
  }
});

module.exports = TodoStore;

View Integration (React)

const React = require('react');
const TodoStore = require('../stores/TodoStore');
const TodoActions = require('../actions/TodoActions');

class TodoApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = { todos: TodoStore.getAll() };
    this._onChange = this._onChange.bind(this);
  }

  componentDidMount() {
    TodoStore.addChangeListener(this._onChange);
  }

  componentWillUnmount() {
    TodoStore.removeChangeListener(this._onChange);
  }

  _onChange() {
    this.setState({ todos: TodoStore.getAll() });
  }

  render() {
    return (
      <div>
        <button onClick={() => TodoActions.create("New task")}>
          Add Todo
        </button>
      </div>
    );
  }
}

References

Related topics