An extended Flux implementation to build isomorphic javascript React app.
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.
- 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!
Read Start from Scratch to know how to create a fluxex application!
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.
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();
}
}
- 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