I like the restrictions that Flux places around data flow but I found it very difficult to get started with. This is a stupidly simple set of data-structuring to allow you to start building a typical web application with React and Flux easily.
The framework/ directory sits along-side your application code so nothing's hidden, extend and hack away at it to build your ideal API. This is just a starting point for your own application framework.
A directory structure and namespace so you can get started.
App =
Stores: {}
Actions: {}
Resources: {}
Components: {}
Filters: {}
Here's how you can create Stores, Actions, Resources and Components:
Stores maintain a set of data, expose public getters, listen to dispatched events that tell them they should update their data, and emit a change
event when they do.
# local data store
things = []
states = {
loading: true
}
# public getters
App.Stores.ThingStore = ThingStore = App.createStore
getState: ->
things: things
states: states
updateThings = (data)->
states.loading = false
things = data
ThingStore.emitChange()
loadThings = ->
states.loading = true
ThingStore.emitChange()
App.Dispatcher.register
'refresh-things': -> loadThings()
'things-refreshed': (data)-> updateThings(data)
Resources are a simple persistence layer where you can put API related methods. They have RESTful methods and translate dates and utc timestamps from strings in your JSON API to JavaScript date objects.
App.Resources.ThingResource = App.createResource
urlRoot: '/api/things'
dateFields: ['delivery_date']
dateTimeFields: ['created_at']
All methods return Promises
ThingResource.query()
ThingResource.where(disabled: true)
ThingResource.get(1)
ThingResource.update(1, { name: 'Thing 2' })
ThingResource.create(name: 'Thing 3')
ThingResource.destroy(1)
Components can fetch data from a Stores public getters and listen to their change
event and fire Actions.
{ ThingStore } = App.Stores
{ ThingActions } = App.Actions
App.Components.Things = React.createClass
getInitialState: ->
ThingStore.getState()
componentDidMount: ->
ThingStore.bind 'change', @onChange
ThingActions.refresh()
componentWillUnmount: ->
ThingStore.unbind 'change', @onChange
onChange: ->
@setState ThingStore.getState()
render: ->
<ul className="things">
{ for thing in @state.things
<Thing {...thing} />
}
</ul>
Actions are entry points for data changes across your application, they can dispatch events to stores and initiate communication with the server.
{ ThingResource } = App.Resources
App.Actions.ThingActions = App.createActions
refresh: ->
@dispatch 'refresh-things'
ThingResource.query (data)->
@dispatch 'things-refreshed', data
Filters are just a place to throw view formatting functions
App.Filters.name = (person)->
"#{ person.first_name } #{ person.last_name }"
- React
- ReactRouter
- Reqwest
- Moment
- MicroEvent
git clone [email protected]:markbrown4/stupid_flux.git
cd stupid_flux
npm start
# run live-server in a separate proccess
npm run live-server
# run json-server in a separate proccess
npm run json-server
I don't know, I've only just started playing with React and Flux so I don't yet know the shortcomings and if there's anything fundamentally wrong with the way data would flow through this design. If you have more experience with it and see gotcha's let me know @markbrown4 👍
I don't think it's an entirely stupid idea though.