Skip to content

Instantly share code, notes, and snippets.

@flarnie
Created December 9, 2014 00:33
Show Gist options
  • Save flarnie/7941289074a609065e78 to your computer and use it in GitHub Desktop.
Save flarnie/7941289074a609065e78 to your computer and use it in GitHub Desktop.
Flux ToDoApp Code Samples
// The 'handleViewAction' dispatches the action to all stores.
// ...
var Dispatcher = require('flux').Dispatcher;
var assign = require('object-assign');
var AppDispatcher = assign(new Dispatcher(), {
/**
* A bridge function between the views and the dispatcher, marking the action
* as a view action. Another variant here could be handleServerAction.
* @param {object} action The data coming from the view.
*/
handleViewAction: function(action) {
this.dispatch({
source: 'VIEW_ACTION',
action: action
});
}
});
// ...
// Saving a new ToDo calls the '_onSave' callback
// ...
var Header = React.createClass({
/**
* @return {object}
*/
render: function() {
return (
<header id="header">
<h1>todos</h1>
<TodoTextInput
id="new-todo"
placeholder="What needs to be done?"
onSave={this._onSave}
/>
</header>
);
},
// ...
// The '_onSave' callback calls the 'TodoActions' method to create an action
// ...
/**
* Event handler called within TodoTextInput.
* Defining this here allows TodoTextInput to be used in multiple places
* in different ways.
* @param {string} text
*/
_onSave: function(text) {
if (text.trim()){
TodoActions.create(text);
}
}
// The 'create' method creates an action of type 'TODO_CREATE'
// ...
var TodoActions = {
/**
* @param {string} text
*/
create: function(text) {
AppDispatcher.handleViewAction({
actionType: TodoConstants.TODO_CREATE,
text: text
});
},
// ...
// Loading the initial data into the application:
// ...
/**
* Retrieve the current TODO data from the TodoStore
*/
function getTodoState() {
return {
allTodos: TodoStore.getAll(),
areAllComplete: TodoStore.areAllComplete()
};
}
var TodoApp = React.createClass({
getInitialState: function() {
return getTodoState();
},
// ...
// The component listens for changes and calls the '_onChange' callback
// ...
var TodoApp = React.createClass({
getInitialState: function() {
return getTodoState();
},
componentDidMount: function() {
TodoStore.addChangeListener(this._onChange);
},
componentWillUnmount: function() {
TodoStore.removeChangeListener(this._onChange);
},
// ...
/**
* Event handler for 'change' events coming from the TodoStore
*/
_onChange: function() {
this.setState(getTodoState());
}
// ...
// The TodoStore has registered a callback for the 'TODO_CREATE' action.
// ...
/**
* Create a TODO item.
* @param {string} text The content of the TODO
*/
function create(text) {
// Hand waving here -- not showing how this interacts with XHR or persistent
// server-side storage.
// Using the current timestamp + random number in place of a real id.
var id = (+new Date() + Math.floor(Math.random() * 999999)).toString(36);
_todos[id] = {
id: id,
complete: false,
text: text
};
}
// Register to handle all updates
AppDispatcher.register(function(payload) {
var action = payload.action;
var text;
switch(action.actionType) {
case TodoConstants.TODO_CREATE:
text = action.text.trim();
if (text !== '') {
create(text);
}
break;
// ...
// TodoStore emits a 'change' event after handling the action.
// ...
// Register to handle all updates
AppDispatcher.register(function(payload) {
var action = payload.action;
var text;
switch(action.actionType) {
case TodoConstants.TODO_CREATE:
text = action.text.trim();
if (text !== '') {
create(text);
}
break;
// ...
default:
return true;
}
// This often goes in each case that should trigger a UI change. This store
// needs to trigger a UI change after every view action, so we can make the
// code less repetitive by putting it here. We need the default case,
// however, to make sure this only gets called after one of the cases above.
TodoStore.emitChange();
return true; // No errors. Needed by promise in Dispatcher.
});
// ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment