Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React, Flux, State and Stores

I find the example todo flux app to be a bit lacking so I'm trying to get my head round things by developing an application to learn and experiment.

The application is a drag and drop fruit basket organiser. I have several baskets which can have various pieces of fruit dragged between them. You can highlight a piece of fruit by clicking on it and the last dragged item will remain highlighted.

Based on this I have 3 stores:

  • FruitStore
  • BasketStore
  • AppStateStore - To track last clicked and last dragged fruit

When a user action occurs a FruitAction is dispatched and handled by either the AppStateStore if the fruit has been clicked or all stores if the fruit has been moved to another basket.

The main AppView component listens to change events from both the FruitStore and the AppStateStore and re-renders.

My questions are:

  • Is this a good approach for this scenario?
  • Should the AppView be listening to multiple stores? How should I prevent the AppView from rendering several times in a row? Right now, when a fruit has been moved, both FruitStore and AppStateStore fire change events causing two renders in a row.
  • The Flux article on the React site shows the view dispatching an action object (e.g. AppDispatcher.dispatch(TodoActions.updateText()) ) but would it be better if the action dispatched itself (e.g. just FruitActions.moveBasket() ) and the AppView is left unaware of the AppDispatcher?
  • Currently only the AppView listens to the stores but should the individual Fruit components listen to the AppStateStore to re-render only themselves if they are to be highlighted?
  • Is there a more complete example of the Flux architecture or something similar?
like image 531
user3687035 Avatar asked May 29 '14 10:05

user3687035


People also ask

What is the flux in React?

What is flux. Flux is a pattern for managing how data flows through a React application. As we've seen, the preferred method of working with React components is through passing data from one parent component to it's children components. The Flux pattern makes this model the default method for handling data.

What is store in flux?

What are Stores? In Flux, Stores are simply a place where data is read out from. More specifically, Views within a Flux architecture will be notified of changes within Stores via the Observer pattern, and then query for those data in order to update their own states.

Which building blocks of flux is used to grab the updated state from the store?

Node's event emitter is used to update the store and broadcast the update to view. The view never directly updates the application state. It is updated because of the changes to the store. This is only part of Flux that can update the data.

What is React flux explained flux data flow structure?

Flux is an application architecture that Facebook uses internally for building the client-side web application with React. It is not a library nor a framework. It is neither a library nor a framework. It is a kind of architecture that complements React as view and follows the concept of Unidirectional Data Flow model.


2 Answers

  • The approach sounds pretty solid. I would create completely different actions for every interaction, e.g. FruitClicked and FruitDragged could both be actions, and the stores would watch for the ones they care about.
  • AppView should listen to all the stores that it gets data from. If you call setState more than once in the same tick, React will intelligently merge them, so you're not actually rendering more than once.
  • The article on the React site does talk about actions that dispatch themselves under Creating Semantic Actions. In the code block a few scroll-lenghts up the page, you can see the code:

    _onDestroyClick: function() { 
      TodoActions.destroy(this.props.todo.id); 
    } 
    
  • The article also talks about which components should listen to stores in Listening to Changes with a Controller-View:

    We need a React component near the top of our component hierarchy to listen for changes in the store. In a larger app, we would have more of these listening components, perhaps one for every section of the page. In Facebook's Ads Creation Tool, we have many of these controller-like views, each governing a specific section of the UI. In the Lookback Video Editor, we only had two: one for the animated preview and one for the image selection interface.

    and

    Occasionally we may need to add additional controller-views deeper in the hierarchy to keep components simple. This might help us to better encapsulate a section of the hierarchy related to a specific data domain. Be aware, however, that controller-views deeper in the hierarchy can violate the singular flow of data by introducing a new, potentially conflicting entry point for the data flow. In making the decision of whether to add a deep controller-view, balance the gain of simpler components against the complexity of multiple data updates flowing into the hierarchy at different points. These multiple data updates can lead to odd effects, with React's render method getting invoked repeatedly by updates from different controller-views, potentially increasing the difficulty of debugging.

  • If you're interested in the flux architecture, you may be interested in Fluxxor (disclaimer: I wrote it), which (hopefully) helps build out a flux-based application. It has a dispatcher that's a little more robust and a few other changes (e.g. non-global stores/actions, React mixins) to make things a bit easier in many cases.
like image 103
Michelle Tilley Avatar answered Sep 20 '22 13:09

Michelle Tilley


It's hard to say whether the approach is a good one without understanding the application a bit more.

However, it seems to me that clicking the fruit should be handled by the FruitStore. That is, a fruit has gained an active state, has become draggable. If this affects the application as a whole somehow, then perhaps this would cause a change in the AppStateStore as well. Likewise, moving a fruit from one basket to another seems like the domain of the BasketStore.

I imagine the FruitStore containing a private data structure like this:

var _fruit = {
  1234: {
    id: '1234',
    type: 'apple',
    active: false
  },
  2345: {
    id: '2345',
    type: 'orange',
    active: false
  },
  3456: {
    id: '3456',
    type: 'apple',
    active: false
  }
};

and I imagine the BasketStore having a private data structure that looks like this:

var _baskets = {
  4321: {
    id: '4321',
    name: 'Josephine\'s Basket',
    fruitIDs: [
      1234,
      2345
    ]
  },
  5432: {
    id: '5432',
    name: 'Harold\'s Basket',
    fruitIDs: [
      3456
    ]
  }
};

Thus the fruit "active" state is managed by the FruitStore, and the contents of the baskets are managed by the BasketStore.

So the AppView can listen to both stores, if this works well for your application. And as mentioned above, there is very little cost to calling the render() method repeatedly. This does not touch the DOM on every call -- this is one of React's greatest strengths. React will instead intelligently batch the calls and only update the "dirty" parts of the DOM, if any exist.

But perhaps you might want to have the baskets become controller-views. If you do choose to make your fruit the controller-views, be sure to cleanup the listeners in componentWillUnmount(), as the movement of fruit from basket to basket may require them to be destroyed and recreated. I think listening at the basket level makes more sense, but again, I don't understand your app that well.

To answer your last question:

Is there a more complete example of the Flux architecture or something similar?

Engineers at Facebook are working on a more complex application example now that will showcase the use of waitFor() and server-side persistent storage. We are hoping to release that soon.

like image 32
fisherwebdev Avatar answered Sep 19 '22 13:09

fisherwebdev