Skip to content

Instantly share code, notes, and snippets.

@mnishiguchi
Created June 3, 2015 19:03
Show Gist options
  • Save mnishiguchi/6b027b526a06aedb06b1 to your computer and use it in GitHub Desktop.
Save mnishiguchi/6b027b526a06aedb06b1 to your computer and use it in GitHub Desktop.
A sample application using React.js and Fluxxor with Ruby on Rails. The application is based on the Fluxxor's documentation.
//= require jquery
//= require jquery_ujs
//= require jquery.turbolinks
//= require bootstrap
//= require turbolinks
//
// React
//= require react
//= require react_ujs
//= require fluxxor
//= require_tree ./react_components
//
//= require_tree .
# Constants (Action types)
constants =
ADD_TODO: 'ADD_TODO'
TOGGLE_TODO: 'TOGGLE_TODO'
CLEAR_TODOS: 'CLEAR_TODOS'
# Stores
TodoStore = Fluxxor.createStore
initialize: ->
@todoId = 0
@todos = {}
@bindActions(constants.ADD_TODO, @onAddTodo,
constants.TOGGLE_TODO, @onToggleTodo,
constants.CLEAR_TODOS, @onClearTodos)
onAddTodo: (payload) ->
id = @_nextTodoId()
todo =
id: id
text: payload.text
complete: false
@todos[id] = todo
@emit 'change'
onToggleTodo: (payload) ->
id = payload.id
@todos[id].complete = not @todos[id].complete
@emit 'change'
onClearTodos: ->
todos = @todos
Object.keys(todos).forEach (key) ->
if todos[key].complete
delete todos[key]
@emit 'change'
getState: -> todos: @todos
_nextTodoId: -> @todoId += 1
# Semantic actions
actions =
addTodo: (text) -> @dispatch constants.ADD_TODO, text: text
toggleTodo: (id) -> @dispatch constants.TOGGLE_TODO, id: id
clearTodos: -> @dispatch constants.CLEAR_TODOS
# Creation of a Flux instance
stores = { TodoStore: new TodoStore }
flux = new Fluxxor.Flux(stores, actions)
# Logging upon the "dispatch" event
flux.on 'dispatch', (type, payload) ->
console.log "[Dispatch]", type, payload if console?.log?
# The main React component (<Application/>)
FluxMixin = Fluxxor.FluxMixin(React)
StoreWatchMixin = Fluxxor.StoreWatchMixin
Application = React.createClass
mixins: [FluxMixin, StoreWatchMixin("TodoStore")]
getInitialState: ->
newTodoText: ""
getStateFromFlux: ->
flux = @getFlux()
flux.store('TodoStore').getState()
handleTodoTextChange: (e) ->
@setState { newTodoText: e.target.value }
onSubmitForm: (e) ->
e.preventDefault()
if @state.newTodoText.trim()
@getFlux().actions.addTodo @state.newTodoText
@setState { newTodoText: "" }
clearCompletedTodos: (e) ->
@getFlux().actions.clearTodos()
render: ->
todos = @state.todos
<div>
<form onSubmit={@onSubmitForm}>
<div className="form-group">
<input type="text" placeholder="New Todo"
value={@state.newTodoText}
onChange={@handleTodoTextChange}
className="form-control" />
</div>
<div className="form-group">
<input type="submit" value="Add Todo" className="btn btn-success"/>
<button onClick={@clearCompletedTodos} className="btn btn-default">Clear Completed</button>
</div>
</form>
<ul>
{
Object.keys(todos).map (id) ->
<li key={id}><TodoItem todo={todos[id]} /></li>;
}
</ul>
</div>
# The React component (<TodoItem/>)
TodoItem = React.createClass
mixins: [FluxMixin]
propTypes:
todo: React.PropTypes.object.isRequired
# Its style will be determined based on the completion state.
render: ->
style =
textDecoration: if @props.todo.complete then "line-through" else ""
<span style={style} onClick={@onClick}>{@props.todo.text}</span>
# Clicking on a todo item will toggle the completion state.
onClick: ->
@getFlux().actions.toggleTodo @props.todo.id
# Render the component.
document.addEventListener 'DOMContentLoaded', (e) ->
React.render <Application flux={flux} />,
document.getElementById 'react_mountPoint'
%h2.page-header
Todo list App using React + Fluxxor + Rails
.panel
.panel-heading Todo list
.panel-body
#react_mountPoint
%p
This app is based on
%a{ href: "http://fluxxor.com/guides/quick-start.html", target: '_blank' }
an example app
of the Fluxxor documentation.
source 'https://rubygems.org'
# ruby 2.2.1p85
gem 'rails', '4.2.1'
gem 'pg', '~> 0.17.1'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '~> 2.7.1'
gem 'coffee-rails', '~> 4.1.0'
gem 'jquery-rails', '~> 4.0.3'
gem 'turbolinks', '~> 2.5.3'
gem 'jbuilder', '~> 2.0'
gem 'sdoc', '~> 0.4.0', group: :doc
# Some gems specific to this example
gem 'haml-rails', '~> 0.9.0' # For HAML.
gem 'react-rails', '~> 1.0.0' # Compiles JSX.
gem 'sprockets-coffee-react', '~> 3.0.1' # Preprocessor for Coffeescript with React JSX (CJSX).
gem 'bower-rails', '~> 0.9.2'
source 'https://rails-assets.org' do
gem 'rails-assets-fluxxor'
end
... other gems are omitted for simplicity
@przeor
Copy link

przeor commented Aug 29, 2016

Hi I see that you use React, so I am sure that you will find interesting the https://reactjs.co - this is the free online convention and tutorial book for React.JS Developers. React is not only the View (in MVC) anymore. ReactJS For Dummies: Why & How to Learn React Redux, the Right Way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment