4

Struggling to find or come up with an elegant answer to this one:

If I have multiple dynamic react components that are listening to one flux store to update their child components is it possible to emit changes to specific components rather than emitting changes to all the components that are registered to listen to changes on that store?

E.G: A dynamic component has a button and when clicked its tells the flux store to send some data to API. The dynamic component will it update its child view depending on the response and change emitted by the flux store. But since all the dynamic components are listening to the store they will all update their child views which is the undesired behaviour. Ideally the flux store could identify which component to emit the change to, or the components can identify that change is not for them.

Is this possible? Or does it go against flux principles?

ChoclateLove
  • 672
  • 1
  • 6
  • 11

2 Answers2

2

I don't know if it violate flux architecture, but it seems not leveraging some beauties of it.

The beauty of a simple emit change (without change detail) is that a store wouldn't need to have explicit knowledge on views, also, with the React Virtual Dom framework, it shouldn't cost too much performance hit.

To further optimize the performance, you can implement shouldComponentUpdate on your React view (base on the differences in it's own properties), to avoid triggering the tree-diff algorithm.

See this: https://facebook.github.io/react/docs/component-specs.html

== Add more info == In more traditional MVC, the model will emit changes to a particular source and with particular details, e.g.

this.emit({
    details: { x: 'x', y: 'y' },
    source: objectA
)};

The view (or controller) that receive this needs such detail to update it's Dom, you will call the update(changes.details) instead of the initial render() method because Dom manipulation is expensive.

ReactJS 'solved' this by having another virtual Dom layer, which use pure Javascript to compute the 'optimal' differences in Dom manipulation, so in React, you never have a method call update(), you will always call render() base on current state of the view, and React does the optimization for you.

So using Flux with React, your store can just emit change without any details and the views that listen to it can just render with 'optimal' Dom manipulation (so if it's state hasn't been changed, there will be no Dom manipulation). But of course, you will say in this case React will still trigger the virtual Dom diff computation, which still cost something. So to further optimize it, you can implement shouldComponentUpdate on a view that contains big sub-tree (base on it's own state), to avoid React to run the diff computation.

The beauty of emit a simple change, besides easier code, is that Store can be pretty much decoupled from view. For example if you trigger specific change details for particular views, then you will need to remove or change code in store(s) when the view is not listening the that store anymore.

Natural Lam
  • 732
  • 4
  • 13
  • Could the one who down voted explain what's the problem? – Natural Lam Oct 23 '15 at 06:05
  • I do not understand the down vote, Francois Richard answer with emitting the id to do the check was the solution I went with, but the validation was done using the shouldComponentUpdate which was suggested by you so I'd like to know the reasoning about the down vote. – ChoclateLove Oct 23 '15 at 10:26
  • actually I don't know, thinking about it maybe it's a good solution, when your store changes you trigger an simple 'change' event, you get the data you need for your component using MyStore[id] and then compare it in componentShouldUpdate. Could be a good solution indeed. – François Richard Oct 23 '15 at 12:34
  • Update your answer I'll upvote, I thought it was a very bad idea but in fact it may be the right way to do. I think I was wrong after all. – François Richard Oct 23 '15 at 12:53
  • Sure. Vote is not the main thing, I am just wondering what's wrong with the arguments, updated the answer to make it more comprehensive – Natural Lam Oct 23 '15 at 16:29
1

It does not go against flux principle but beware not having only one big store, sometime it's better to split in several tiny store. But I think I understand your use case, one store containing a collection of similar objects (like a backbone collection).

So lets say your store receive a new object or an array of new object (or things to update in your store), you have a register function which will add this object (or update) to your store. For sure this object has an id field (or something similar). Then for each new object of your array you just received you'll emit the id.

And your view are binded to their id as change event. Basically you use your store like an array, when the array is change you emit the key as event. Your view listen to this key/id and then get the specific data from your store still using this id/key.

Hope it's clear, let me know.

François Richard
  • 6,817
  • 10
  • 43
  • 78