React: Flux

  • Presentation
  • Lab

Flow chart!

Views

// components/add-customer.jsx

var React = require('react');
var CustomerActionCreator = require('../actions/CustomerActionCreator');

module.exports = React.createClass({
  displayName: 'AddCustomer',
  addCustomer: function () {
    var name = this.refs.name.getDOMNode().value;
    CustomerActionCreator.addCustomer(name);
  },
  render: function () {
    return (
      <div className="add-customer">
        <input type="text" ref="name" />
        <button onClick={this.addCustomer}>Add Customer</button>
      </div>
    );
  }
});

Action Creators

// actions/CustomerActionCreator.js

var AppDispatcher = require('../dispatchers/AppDispatcher');

module.exports = {
  addCustomer: function (name) {
    AppDispatcher.dispatch({
      type: 'ADD_CUSTOMER',
      name: name
    });
  };
};

Stores (part 1)

 

// stores/CustomerStore.js

var EventEmitter = require('events').EventEmitter;
var _ = require('underscore');
var ShopDispatcher = require('../dispatcher/ShopDispatcher');

var CHANGE_EVENT = 'change';

var customers = [];

var CustomerStore = _.extend({}, EventEmitter.prototype, {
  emitChange: function () {
    this.emit(CHANGE_EVENT);
  },
  addChangeListener: function (callback) {
    this.on(CHANGE_EVENT, callback);
  },
  removeChangeListener: function (callback) {
    this.removeListener(CHANGE_EVENT, callback);
  },
  getCustomers: function () {
    return customers;
  }
});

Stores (part 2)

// stores/CustomerStore.js

function addCustomer(name) {
  customers.push(name);
}

AppDispatcher.register(function (action) {
  switch (action.type) {
    case 'ADD_CUSTOMER':
      addCustomer(action.name);
      CustomerStore.emitChange();
      break;
    default:
      break;
  }
});

module.exports = CustomerStore;

Dispatcher

// dispatchers/AppDispatcher.js

var Dispatcher = require('flux').Dispatcher;

module.exports = new Dispatcher();

Listen for changes

// components/customer-list.jsx

var React = require('react');
var CustomerStore = require('../stores/CustomerStore');

module.exports = React.createClass({
  displayName: 'CustomerList',
  getInitialState: function () {
    return {
      customers: CustomerStore.getCustomers()
    };
  },
  componentWillMount: function () {
    CustomerStore.addChangeListener(function () {
      this.setState({
        customers: CustomerStore.getCustomers()
      });
    });
  },
  render: function () {
    var customers = this.state.customers.map(function (name) {
      return <li>{name}</li>;
    });
    return (
      <ul className="customers">
        {customers}
      </ul>
    );
  }
});

Lab!

https://github.com/jayway/react-flux-lab

Made with Slides.com