I have my own opiniated way on how to use React and am building my own framework, inspired by Om. I am implementing something a bit similar to the Flux architecture, with stores that can update themselves on some events.
What I am not sure to understand is why in the Flux architecture do we need store dependencies?
Stores aren't supposed to be self-contained data holders for a given bounded context, like we do with CQRS architectures?
In an evented system, 2 CQRS components could end up holding the same data. Do we express store dependencies to avoid holding duplicate data in stores?
Can someone come up with some very concrete use cases where store dependencies are needed and where the problem can hardly be solved in any other way? I can't find any myself.
Flux is the application architecture that Facebook uses for building client-side web applications. It complements React's composable view components by utilizing a unidirectional data flow. It's more of a pattern rather than a formal framework, and you can start using Flux immediately without a lot of new code.
The primary difference of Flux vs Redux is that Flux includes multiple Stores per app, but Redux includes a single Store per app. Rather than placing state information in multiple Stores across the application, Redux keeps everything in one region of the app.
Flux manages complicated interactions between data resources. Flux has a unidirectional data flow. Which means it is easier to manage the data flow.
In refluxjs we solve waitFor
in a couple of ways, one for the sequential data flow and the other for the parallel data flow. I try to model the data stores in a way to avoid holding the same data (i.e. double maintenance data).
Basically, data stores are CQRS components, and I try to avoid having 2 data stores end up with the same kind of data. If I need to transform the data somehow that only some components need, I break that out to an "aggregate" data store. Naïve implementation:
var carsStore = Reflux.createStore({
init: function() {
this.listenTo(Actions.updateCars, this.updateCallback);
},
updateCallback: function() {
$.ajax('/api/cars', {}).done(function(data) {
this.trigger(data.cars);
}.bind(this));
}
});
We can create another data store that aggregates the data by listening to the carsStore
:
var modelsStore = Reflux.createStore({
init: function() {
this.listenTo(carsStore, this.carsCallback);
},
carsCallback: function(cars) { // passed on from carsStore trigger
this.trigger(this.getModels(cars)); // pass on the models
}
getModels: function(cars) {
return _.unique(_.map(cars, function(car) { return car.model; }));
}
});
That way your React view components may use one to get the cars and the other to get the models, which is aggregated from the carStore
.
If a store needs to wait for two parallell data streams to complete we provide the Reflux.all
to join actions and stores. This is useful e.g. if you're waiting for data to load from seperate different REST resources.
var carsAndPartsAreLoaded = Reflux.all(carStore, partsStore);
// you may now listen to carsAndPartsAreLoaded
// from your data stores and components
Hope this makes sense to you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With