From what I've read the pattern is the Components pass data to the Actions which Pass to the Store whose value changes trigger updates in Components that subscribe to the Stores. My question is how to "react" to these triggered updates in the form of a notification? ( ie a successfully saved notification )
Ie do I add logic to the render of this notification component that only displays itself if there is a some flag attribute in the object that its subscribed to? Then deletes itself after a time. This sounds wrong.
UPDATE
Thanks to Hannes Johansson I think I have a better grasp of a pattern. What I have working is the following:
Component passes data through action to the Store
The Store interacts with the api and adds a flag to the model that the component is now notified of an updated model.
createItem: function (item) {
$.ajax({
url: '/items',
method: 'POST',
data: item,
success: function (item) {
CurrentBrandActions.addCampaign(item);
this.item = item;
item.newlyCreated = true;
this.trigger(item);
}.bind(this)
})
}
The Component sees the flag and renders a "Notification Child Component"
var newlyCreated = this.state.item.newlyCreated === true;
if (newlyCreated) {
newlyCreated = <ItemCreatedNotification item={this.state.item} />
} else {
newlyCreated = '';
}
return (
<form onSubmit={this.createItem} className="form">
{newlyCreated}
Something needs to move the app to a new place based on this event. Should this be a) the Notification Child Component b) Parent Component c) The Store?
According to Colin Megill's talk on flux api patterns the api interaction should occur in the Action, but reflux doesn't really allow for that.
UPDATE 2
Component passes data to an Action called createItemRequest
The Action has a preEmit hook that actually does the api call. The createItemRequest
continues to the Store so that the store can change the model to reflect the state of sending which is then displayed in the component( maybe show a spinner ). The Action is also responsible for firing two other events depending on the api result.
ItemActions.createItemRequest.preEmit = function (data) {
$.ajax({
url: '/items',
method: 'POST',
data: data,
success: function (item) {
ItemActions.itemCreatedSuccess(item);
},
error: function (error) {
ItemActions.itemCreatedError(error);
}
});
}
There are different approaches to this. For example, in Reflux it's very easy to listen directly to actions if you choose to, since each action is actually a "dispatcher".
However, the general, purist Flux principle is that only stores register with the dispatcher and that components only listen to store updates. And the store just trigger an event that notifies that something has changed, not providing any payload. Then it's up to the component to read the store's state and determine how to render it.
One approach would be the one you describe, put some flag on the items in the store to signal that an update has happened, but it would violate the Flux principle if the components themselves then update the stored items' flags, since only stores are meant to mutate state, and only in response to actions and not from any other source. So in that case the "Flux thing" to do would probably be to trigger yet another event that signals that the newly added item has been noted so that the store can then reset the flag in response to that action.
Another approach I can think of would be to diff the state in your component when it gets notified of a store update. Then keep the flags only in the component, or even keeping newly added items in a separate list in the state and render them separately.
There are no hard rules here, except that if you want to follow the core Flux principle, components should never directly mutate stores' state, because that should only be mutated by the stores themselves in response to actions. That allows for a uni-directional data flow and a single source of truth about the data, which is the main goal of Flux.