FluxEx
An extended Flux implementation to build isomorphic javascript React app.
Features
All in one Starter
Everything in React
Minimal context APIs
To understand Flux, you only need to learn these APIs: this.executeAction()
, this.getStore()
, this.dispatch()
!
this.executeAction()
orthis.getStore(name)
in components.this.dispatch()
orthis.executeAction()
orthis.getStore(name)
in actions.this.emitChange()
orthis._get()
orthis._set()
in stores.
- [CORE] Super lightweight, less than 250 lines of code.
- [CORE] Context based flux system.
- [CORE] React Server side rendering + client mount.
- [CORE] HTML as top level react component, no need container.
- [EXTRA] express middleware to serve the fluxex application.
- [EXTRA] full integrated gulp task for development.
- [EXTRA] pjax support.
- [EXTRA] rpc and api call support.
See the FluxEx Magic
- Check example projects you can see how fluxex do server side rendering + context deliver + Full HTML react rendering!
- No more index.html. Start with npm:express and your Html.jsx!
- No more AJAX, all http request by npm:request!
Start from Scratch
Read Start from Scratch to know how to create a fluxex application!
Quick Start
Prepare your project
npm init
npm install fluxex
Use the Starter template
node_modules/.bin/fluxex_starter
Start the Server
node_modules/.bin/gulp develop
- Connect to http://localhost:3001/search?q=pizza
- You can start your development now, gulp handled everything (jshint, browserify, nodemon, restart, browser-sync).
- Put your actions, stores and components into correspond directories.
- Edit components/Html.jsx to include your React components.
- Edit actions/routing.js to add routing.
- Edit fluxexapp.js to add your store.
Difference with Flux
FluxEx is context based flux implemention. Server side react rendering can be done easy when the flux is scoped under a request based context. Store and dispatcher are singletons in Facebook flux, but in fluxex they are not.
**Fluxex** * Fluxex is an instance, it is constructed by provided context. * Fluxex can be serialized by `.toString()` and reconstructed by the serialized string. All server side store status can be transfered to client side by this way. * use the static `.createApp()` to create a Fluxex application.
var myApp = require('fluxex').createApp({
product: require('./stores/product')
}, process.cwd() + '/components/Html.jsx');
**Action** * An action creator should return a promise. * An action creator function can be executed by `.executeAction()`. * When the action be `.executeAction()`, the Fluxex instance can be referenced by `this`. * `.executeAction()` will return a promise, so you can manage asynchronous actions in promise way.
// inside a component, requires Fluxex.mixin
...
onStoreChange: function () {
return this.getStore('myStore').getSomething();
},
handleClick: function () {
this.executeAction(myAction);
}
**Dispatcher** * the Fluxex instance itself is a dispatcher with `.dispatch()` method. * the dispatched `FOOBAR` action will trigger all `handle_FOOBAR` method of all stores. When there is no `handle_FOOBAR` method in any store, an error will be throw.
// myAction
var myAction = function (payload) {
... do your tasks ....
return this.dispatch('UPDATE_SOMETHING', ....); // this returns a promise
}
**Store** * Store is an instance, it is constructed by serialized status. * Store is created by a Fluxex. * Use `.getStore(name)` to get the store by name. * You can `._get()` and `._set()` by property name. Ex: `this._set('data', 123)` * Everything you `._set()` can be serialized by `.toString()` and be tracked by your Fluxex application. * You can use `waitFor` property to refine dispatch depdency for specific action.
var myStore = {
// the dispatch will happened after these stores be dispatched
waitFor: {
UPDATE_SOMETHING: ['oneStore', 'anotherStore']
},
// handle this.dispatch('UPDATE_SOMETHING', ....)
handle_UPDATE_SOMETHING: function (payload) {
this._set('data', payload); // There are ._get() and ._set() in all stores
this.emitChange();
}
}
Notes for IE8 support
- NOTE React v15+ stop supporting IE8
- You should add
require('fluxex/extra/polyfill-ie8');
in yourfluxexapp.js
to polyfill EventListener methods and XMLHttpRequest consts for IE8. catch
is reserved keyword in IE8, you need to replacesomePromise.catch(...)
withsomePromise['catch'](...)
for (... in ...)
will loop beyond properties in IE8, you need to replacefor (I in myArray)
withmyArray.forEach(function (V, I) { ...}
IE8 Unsupported features
- window.history.pushState
- set innerHTML of script or title node
- compare prototype.constructor with another function
- console and console.log when developer tool not opened