I am using Fluxxor and React Js and stuck with the following problem:
My React class is subscribed to several stores using mixins. My stores send this.emit("change") and I react to them in the function getStateFromFlux of the React class. But I want to know from which store I got a state change.
How can I do this ?
Thanks !
Probably the best way is to create different listeners for different stores. So, you might have onXStoreChange, onYStoreChange, etc. But there's another trick you can use, if you choose to. When you call the emit function within your store, announcing a change, you can pass other args with it as well that will then be available to the listening component.
One thing you could pass is the store from which the change originated. Based on that, you could then know which store to ask for state info.
Related
I'm starting to learn about vuex. I have the question should I set this data from the Store or should I load it on the component?
For example, In my app, I load all users (firebase) from a Store Action and read it from the Getters, but when it comes to load one user data, should I fetch it from the state and then to the component or from the component itself?
I just want to make sure to make my life easier when updating or adding a new feature on the app.
Your store should be your only source of truth for global state.
This means that any component that read data should read from the store. This ensures consistency. Of course each component may need some local data, that it gets using other means and can alter the data that it gets from the store, but it should read from there.
Now you only have a dilemma regarding who should write to the store (using mutations and actions). This depends heavily on your use cases. It is perfectly acceptable to write from the components itself.
There are use cases where populating some data from outside any component makes sense. Probably the most common case is auth credentials. It is easier and cleaner to populate auth credentials before mounting the app for instance so you have one choke point for dealing with authed/unauthed users.
Bottom line is, writing to the store depends on your use case and there's no silver bullet here.
If I use react with redux - does it always necessary to fetch data from the redux action? Or it depends if I need the data to be stateful?
For example: I have a container which displays a user profile page. Can I fetch its data from the componentDidMount?
Thanks.
Below a list of rules of thumb which could help you to determinate what kind of data should be put into Redux or in your component, I tried to write down few assumptions, but please in mind you know only the right answers :):
Is the data used by other part of your application? Probably in your case yes as a User Profile property like name could be used in different components, like the head of your site, profile details, basket.
Do you need to be able to create further derived data based on this original data?
Is the same data being used by multiple components? Probably yes.
Do you need to cache the data? Probably no.
Yes - this is how you would fetch it if there wasn't redux being used.
If you want to use redux (to make profiles available in general etc.), you should call the action from componentDidMount to properly handle lifecycle events etc.
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?
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.
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.
I am new on React and Flux and I am making an app that will have an input (like the name or the title), and below a list of n things.
How should I handle the event listeners? I saw in the TODO example of flux (https://github.com/facebook/flux/blob/master/examples/flux-todomvc/) that they use one change listener and emit an event with all the store state on every change.
Is that ok for a real app? If not, what could I do?
Yes, that is okay for a real app. It is typical to emit whole objects from stores even if it just so happens one of the listeners only needs a subset of the data. The idea is to keep it simple and avoid having to change the store when what the listener needs changes.
I am just getting started with Flight.js and realized that component instances share local variables, but didn't find anything about it in the documentation.
This is what i mean:
flight.component(function () {
var sharedBetweenAllInstances = true;
this.notShared = true;
}).attachTo('.multiple-elements');
As example, if a component should count clicks on it, it could increment this.clicksCount for the number of clicks on each single instance, and increment var totalClicks for the total number of clicks on any instance of the component.
I didn't find anything about this in the documentation, so I wonder if flight components should be used this way?
Thank you!
I don't think that's a good idea (probably why they don't mention it in the docs). The function you setup as your "component" is actually applied as a functional mixin, along with any other mixins your component uses. So, while you might be able to access that variable when doing an .attachTo('.multip-selector') where you're setting up an instance on each of many components, you could still run into problem if attaching individually, or if the shared variable controls resources in which a race condition to access that shared resource becomes problematic.
From a "component" standpoint, you're better off pulling out any shared state into a separate data component or controller type component that can receive updates form the individual components and broadcast the shared state when it's updated.
Here's an example I put together using that scenario via jsbin: http://jsbin.com/qecupi/edit?js