FLUX
Une architecture pour le JavaScript front-end
ChtiJS #13 - 2/07/2015

MOI (UN PEU QUAND MÊME)

- Tom Panier aka neemzy
- Ingénieur SI chez CGI
- Dev PHP et expert technique pour Auchan E-Commerce France
- Fait aussi du JS, dont entre autres du React
C'EST L'HISTOOOIRE
D'UNE APPLIII

LE CONTEXTE
- Appli métier back-office
- UI fabriquée avec React
- Beaucoup d'avantages
- Des utilisateurs comblés
- Des devs aux anges
MAIS UN BEAU MATIN...

C'EST LE BORDAYL
Problème
- Beaucoup de composants React...
- ...qui font des appels AJAX, implémentent de la logique...
- ...bref, qui font le café.
SOLUTIONS
- Passer sur Angular
- Restructurer l'appli
</troll>

Flux
- Ni librairie, ni framework : un modèle d'architecture
- Conçu par Facebook
- Basé sur (mais découplé de) React
- Plus adapté au front-end que le MVC
EXEMPLE > EXPLICATION
var ItemApp = (function () {
return React.createClass({
getInitialState: function() {
return { items: [] };
},
fetchItems: function() {
taLibAjaxFavorite
.get('/items')
.then(function (items) {
this.setState({ items: items });
});
},
createItem: function(data) {
taLibAjaxFavorite
.post('/items', data)
.then(function (items) {
this.setState({ items: items });
});
}
componentWillMount: function() {
this.fetchItems();
},
render: function() {
return (
<div>
<h1>Super useful item list</h1>
<ItemList items={this.state.items} />
<ItemForm createItem={this.createItem} />
</div>
);
}
});
})();
POURKOI CÉ MAL ?
- La vue communique directement avec le serveur
- React gère les données dans les deux sens
var ItemApp = (function () {
var getAppState = function() {
return { items: ItemStore.getItems() }; // Store
};
return React.createClass({
getInitialState: function() {
return getAppState();
},
onChange: function() {
this.setState(getAppState());
},
componentWillMount: function() {
ItemActions.fetchItems(); // Action
},
componentDidMount: function() {
ItemStore.addChangeListener(this.onChange); // Store
},
componentWillUnmount: function() {
ItemStore.removeChangeListener(this.onChange); // Store
},
render: function() {
return (
<div>
<h1>Super useful item list</h1>
<ItemList items={this.state.items} />
<ItemForm createItem={ItemActions.createItem /* Action */} />
</div>
);
}
});
})();
SURVOL
- Actions
- Dispatcher
- Stores
ACTIONS
var ItemActions = (function () {
return {
fetchItems: function() {
Dispatcher.handleAction({
actionType: Constants.ITEM_FETCH
});
},
createItem: function(data) {
Dispatcher.handleAction({
actionType: Constants.ITEM_CREATE,
data: data
});
}
};
})();
DISPATCHER
var Dispatcher = (function () {
var dispatcher = new Flux.Dispatcher(); // dépendance 1
dispatcher.handleAction = function(action) {
this.dispatch({
action: action
});
};
return dispatcher;
})();
STORES
var ItemStore = (function () {
var items = [],
loadItems = function(data) {
items = data;
},
store = {};
Object.assign(
store,
EventEmitter.prototype, // dépendance 2
{
getItems: function() {
return items;
},
emitChange: function() {
this.emit('change');
},
addChangeListener: function(callback) {
this.addListener('change', callback);
},
removeChangeListener: function(callback) {
this.removeListener('change', callback);
}
}
);
// ...
// ...
Dispatcher.register(function (payload) {
switch (payload.action.actionType) {
case Constants.ITEM_FETCH:
taLibAjaxFavorite
.get('/items')
.then(function (data) {
loadItems(data);
store.emitChange();
});
break;
case Constants.ITEM_CREATE:
taLibAjaxFavorite
.post('/items', { value: payload.action.data })
.then(function (data) {
loadItems(data);
store.emitChange();
});
break;
}
return true;
});
return store;
})();
LE RÉSULTAT ?
- Code plus clair, lisible, maintenable...
- Des devs (de nouveau) aux anges
MERCI !

Flux : une architecture pour le JavaScript front-end
By neemzy
Flux : une architecture pour le JavaScript front-end
ChtiJS #13 - 2/07/2015
- 4,797