Comment éviter l'envoi au milieu d'une dépêche
Dans mon Flux de l'architecture de Réagir application que je suis la récupération de données à partir d'un magasin, et voudrais créer une action de demander cette information si elle n'existe pas. Cependant, je suis en cours d'exécution dans une erreur si le répartiteur est déjà de l'expédition.
Mon code désiré est quelque chose comme:
getAll: function(options) {
options = options || {};
var key = JSON.stringify(options);
var ratings = _data.ratings[key];
if (!ratings) {
RatingActions.fetchAll(options);
}
return ratings || [];
}
Cependant par intermittence échoue lorsque le répartiteur est déjà l'envoi d'action, avec le message Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.
. Je suis souvent en faisant des demandes en réponse à un changement dans l'état de l'application (par exemple, la plage de dates). Mon composant où je en faire la demande, en réponse à un événement de modification de la AppStore
est la suivante:
getStateFromStores: function() {
var dateOptions = {
startDate: AppStore.getStartISOString(),
endDate: AppStore.getEndISOString()
};
return {
ratings: RatingStore.getAll(dateOptions),
};
},
Je suis conscient que l'événement le chaînage est un Flux antipattern, mais je suis pas sûr de ce qu'est l'architecture de mieux pour récupérer les données lorsqu'il n'existe pas encore. Actuellement, je suis en utilisant cette terrible hack:
getAll: function(options) {
options = options || {};
var key = JSON.stringify(options);
var ratings = _data.ratings[key];
if (!ratings) {
setTimeout(function() {
if (!RatingActions.dispatcher.isDispatching()) {
RatingActions.fetchAll(options);
}
}, 0);
}
return ratings || [];
},
Quelle serait une meilleure architecture qui permet d'éviter les cas de chaînage ou le répartiteur d'erreur? Est-ce vraiment le cas de chaînage? Je veux juste changer la base de données sur les paramètres de l'application.
Merci!
source d'informationauteur Ian Walker-Sperber | 2015-05-20
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser le Flux
waitFor()
fonction au lieu d'un setTimeoutPar exemple, vous avez 2 magasins enregistrés pour le même répartiteur et ont un magasin waitFor l'autre magasin pour le processus de l'action d'abord, puis l'un l'attente peut être mise à jour après l'envoi de l'événement de changement. Voir le Flux docs exemple
Mon erreur a été produit en raison de mes magasins émis leur événement de changement de cours de l'action de l'expédition, alors qu'il était encore à vélo à travers les écouteurs. Cela signifiait que tout les auditeurs (ie) alors déclenché une action en raison d'une modification de données dans le magasin interrompre l'envoi. Je l'ai fixée par l'émission de l'événement de changement après l'expédition avait terminé.
Donc:
Est devenu
Encore un peu hacky (probablement réécrire donc ne nécessite pas un
setTimeout
). Ouvert à des solutions qui répondent à l'architecture problème, plutôt que de détail d'implémentation.La raison pour laquelle vous obtenez une expédition dans le milieu d'une précédente expédition, est que votre boutique distribue d'une action (invoque une action créateur) de façon synchrone dans le gestionnaire pour une autre action. Le répartiteur est techniquement jusqu'à la livraison à tous ses rappels enregistrés ont été exécutées. Donc, si vous l'envoi d'une nouvelle action de la part des deux rappels enregistrés, vous obtiendrez cette erreur.
Toutefois, si vous de faire de l'asynchrone de travail, par exemple, faire une requête ajax, vous pouvez toujours envoyer une action dans les rappels ajaxou async rappel général. Cela fonctionne, parce que dès que l'asynchrone en fonction a été appelée, par définition reprend immédiatement l'exécution de la fonction et met le rappel sur la file d'attente des événements.
Comme l'a souligné Amida et dans les commentaires de cette réponse, c'est une question de choix que de faire des requêtes ajax à partir de la boutique en réponse à une action, ou si le faire dans le magasin. La clé, c'est qu'une banque ne doit muter son état en réponse à une actionpas dans un ajax/async rappel.
Dans votre cas particulier, ce serait illustré par quelque chose comme ça pour votre magasin de rappel enregistré, si vous préférez faire les appels ajax à partir de la boutique:
Ou vous pouvez simplement mettre l'appel ajax dans votre action de créateur et de l'expédition de la "réussite/échec" actions à partir de là.
Dans mon cas, j'ai récupérer des données à travers les actions/mesures de créateurs. Le magasin est seulement un cliché qui reçoit la charge utile d'une action.
Cela signifie que je "fetchall" dans une action, puis de transmettre le résultat à la banque qui va faire ce que avec elle et puis émet un événement de changement.
Certaines personnes considèrent que l'aide de magasins comme moi, d'autres pensent comme vous.
Certaines personnes à Facebook utilise "mon" approche:
https://github.com/facebook/flux/blob/19a24975462234ddc583ad740354e115c20b881d/examples/flux-chat/js/utils/ChatWebAPIUtils.js#L51
Je pense qu'il serait probablement éviter l'envoi problème le traitement de vos magasins de ce genre, mais je me trompe peut-être.
Une discussion intéressante est celle-ci: https://groups.google.com/forum/#!topic/reactjs/jBPHH4Q-8Sc
où Jing Chen (Facebook de l'ingénieur) explique ce qu'elle pense sur la façon d'utiliser les magasins.
vous pouvez l'utilisateur le "reporter" option dans le répartiteur.
Dans votre cas, il serait comme: