Confused about React's Flux architecture - waitFor
Asked Answered
I

2

9

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.

Iona answered 10/8, 2014 at 12:6 Comment(2)
Where did you end up on this?Resilience
@Resilience check github.com/stample/atom-react . Also Dan Abramov is experimenting store composability instead of dependency (I somehow do this too). See gist.github.com/gaearon/d77ca812015c0356654fIona
I
1

I've finally built an application with something akin to Flux stores without any dependency.

Recently Dan Abramov created a framework (Redux) that highlights flux stores composability, without the need of any store dependency or waitFor, and I share most of his ideas

Iona answered 15/7, 2015 at 16:5 Comment(0)
F
4

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.

Ferule answered 11/8, 2014 at 14:26 Comment(5)
We will be looking into making CRUD commands easy to handle in reflux against offline local storage and adaptor for a web api. This will most likely become an extension, as refluxjs core may be used server-side (in NodeJS).Ferule
I think duplicating the data is actually the solution to not have any dependency between Flux stores and to not have to deal with store synchronization thus. What do you think of this? msdn.microsoft.com/en-us/library/bb245672.aspxIona
@SebastienLorber Why do you feel the need to not have dependencies between stores? One of the pain points Facebook tried to alleviate with Flux was to avoid dealing with transitive data in components, which was a major source of bugs (according to the video). Synching data within the web application is solved automatically in Flux by signalling or passing around the data in a predictable uni-directional flow.Ferule
Sorry but I don't understand what you mean by transitive data between components nor which part of which video you refers to. I think making autonomous stores is also very predictable as the store events become the source of truth and it scales better on large codebase, as when developing one component, you don't need to understand how other components work but just the business events that can be fired. In your Flux design, tell me it never happens that you want to refactor one store and have to refactor another store as a side effect?Iona
@SebastienLorber Oops. I meant "derived data", they're discussing this with a use case in the video around 14:00-17:00 mins. I think we're on the same page regarding the store events "becoming the source of truth". In reflux you wire up the components (stores and react components alike) by subscribing to events on actions or other stores. They will receive the event data from a store rather knowing what it does internally and you're not supposed to know the exact interface of the stores you're listening to.Ferule
I
1

I've finally built an application with something akin to Flux stores without any dependency.

Recently Dan Abramov created a framework (Redux) that highlights flux stores composability, without the need of any store dependency or waitFor, and I share most of his ideas

Iona answered 15/7, 2015 at 16:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.