J'ai actuellement reçu une situation où j'ai besoin de Redux Actions à exécuter consécutivement. J'ai pris un coup d'oeil à différents middlewares, tel un redux-promesse, qui semblent être bien si vous savez ce que les actions successives sont à la pointe de la racine (par manque d'un meilleur terme) de l'action déclenchée.
Essentiellement, je tiens à maintenir une liste d'actions qui peuvent être ajoutés à tout moment. Chaque objet est une instance de cette file d'attente dans son état et dépendant des actions peuvent être mis en file d'attente, le traitement et l'retiré en conséquence. J'ai une mise en œuvre, mais en le faisant, je suis donc d'accéder à l'état de mon action créateurs, qui se sent comme un anti-modèle.
Je vais essayer et donner un peu de contexte sur les cas d'utilisation et de mise en œuvre.
Cas D'Utilisation
Supposons que vous voulez créer plusieurs listes et de les conserver sur un serveur. Sur la création d'une liste, le serveur répond avec un id pour cette liste, qui est utilisé dans la suite de l'API fin des points ayant trait à la liste:
http://my.api.com/v1.0/lists/ // POST returns some id
http://my.api.com/v1.0/lists/<id>/items // API end points include id
Imaginez que le client veut effectuer optimiste mises à jour sur ces API points, afin d'améliorer l'UX - personne n'aime regarder les filateurs. Ainsi, lorsque vous créez une liste, votre nouvelle liste s'affiche instantanément, avec une option à ajouter des éléments:
+-------------+----------+
| List Name | Actions |
+-------------+----------+
| My New List | Add Item |
+-------------+----------+
Supposons que quelqu'un tente d'ajouter un élément avant la réponse de la création initiale d'appel a fait de retour. Les éléments de l'API dépend de l'id, alors nous savons que nous ne pouvons l'appeler jusqu'à ce que nous ont données. Cependant, on peut vouloir optimiste montrer le nouvel élément et mettre en file d'attente un appel aux éléments de l'API afin qu'il déclenche une fois que créer l'appel est fait.
Une Solution Potentielle
La méthode que j'utilise pour contourner ce problème actuellement est en donnant à chaque liste une action de file d'attente, qui est, une liste de Redux actions qui seront déclenchées dans la succession.
Le réducteur de fonctionnalités pour la création d'une liste pourrait ressembler à quelque chose comme ceci:
case ADD_LIST:
return {
id: undefined, // To be filled on server response
name: action.payload.name,
actionQueue: []
}
Puis, dans une action créateur, nous aimerions mettre en file d'attente d'une action au lieu de déclenchement:
export const createListItem = (name) => {
return (dispatch) => {
dispatch(addList(name)); // Optimistic action
dispatch(enqueueListAction(name, backendCreateListAction(name));
}
}
Par souci de concision, d'assumer la backendCreateListAction appels de fonction d'une extraction de l'API, qui distribue les messages à la file d'attente à partir de la liste sur la réussite/échec.
Le Problème
Ce qui m'inquiète ici est la mise en œuvre de la enqueueListAction méthode. C'est là que je suis accéder à l'état de regler la progression de la file d'attente. Il ressemble à quelque chose comme ceci (ignorer cette mise en correspondance sur le nom - ce qui utilise un clientId dans la réalité, mais j'essaie de garder l'exemple simple):
const enqueueListAction = (name, asyncAction) => {
return (dispatch, getState) => {
const state = getState();
dispatch(enqueue(name, asyncAction));{
const thisList = state.lists.find((l) => {
return l.name == name;
});
// If there's nothing in the queue then process immediately
if (thisList.actionQueue.length === 0) {
asyncAction(dispatch);
}
}
}
Ici, nous supposons que la mise en file d'attente méthode renvoie une simple action qui insère une action asynchrone dans les listes actionQueue.
Le tout sent un peu à contre-courant, mais je ne sais pas si il y a un autre chemin pour aller avec elle. En outre, depuis que j'ai besoin pour l'expédition dans ma asyncActions, j'ai besoin de passer à la méthode dispatch vers le bas.
Il y a un code similaire dans la méthode à retirer de la liste, ce qui déclenche l'action suivante existe:
const dequeueListAction = (name) => {
return (dispatch, getState) => {
dispatch(dequeue(name));
const state = getState();
const thisList = state.lists.find((l) => {
return l.name === name;
});
// Process next action if exists.
if (thisList.actionQueue.length > 0) {
thisList.actionQueue[0].asyncAction(dispatch);
}
}
Généralement, je peux vivre avec cela, mais je suis préoccupé par le fait que c'est un anti-modèle, et il serait peut-être plus concis, idiomatiques façon de le faire dans Redux.
Toute aide est appréciée.