Je travaille sur une application React qui utilise l'architecture suivante:
redux typesafe-actions redux-observable Ma question est la suivante: comment puis-je exécuter une action d'interface utilisateur sur une action redux spécifique?
Par exemple, supposons que nous ayons les actions asynchrones suivantes définies avec typesafe-actions code>:
import { Actions } from '@ngrx/effects';
@Component(...)
class SomeComponent implements OnDestroy {
constructor(updates$: Actions) {
updates$
.ofType(PostActions.SAVE_POST_SUCCESS)
.takeUntil(this.destroyed$)
.do(() => /* hooray, success, show notification alert ect..
.subscribe();
}
}
Un Epic recherchera listTodo.request () et enverra l'appel API, puis convertira la réponse en listTodo.success () action. Ensuite, le réducteur de redux sera déclenché par l'action listTodo.success () et stockera la liste de tâches dans le magasin de redux.
Dans ce paramètre, supposons que je veuille faire les choses suivantes dans un composant:
listTodo.request () pour récupérer toutes les actions listTodo.success () dans le flux d'actions), redirigez l'interface utilisateur vers un deuxième chemin Ma question est donc la suivante: comment pourrais-je regarder le flux d'action et réagir à l'action listTodo.success () ?
MISE À JOUR: Pour éviter d'être trop précis, nous pouvons penser à un autre cas. Je veux simplement afficher une alerte avec window.alert () après que listTodo.success () apparaisse dans le flux d'actions. Ou simplement console.log () , ou tout ce qui change l'état local (au lieu de l'état redux global). Existe-t-il un moyen de mettre en œuvre cela?
UPDATE 2: Il y a une question similaire ici , mais pour Angular w / ngrx. Ce que je veux faire est exactement la chose décrite dans le post ci-dessus, mais de manière React / redux-observable:
export const listTodo = createAsyncAction( 'TODO:LIST:REQUEST', 'TODO:LIST:SUCCESS', 'TODO:LIST:FAILURE', )<void, Todo[], Error>();
3 Réponses :
Avec redux, les composants sont mis à jour en fonction de l'état.
Si vous souhaitez mettre à jour un composant en fonction d'une action, mettez à jour l'état dans le réducteur, tel que la définition de {... state, success: true} dans le réducteur. De là, vous lisez simplement l'état dans votre composant comme vous le feriez normalement et si l'état change en succès, vous affichez votre fenêtre.
Merci @ ralph-ritoch pour la solution. J'ai un peu l'impression que ce serait moins résistant aux erreurs - que se passe-t-il s'il y a d'autres actions qui mettent également à jour l'état de succès ? que se passe-t-il si l'action «demande» asynchrone d'origine est émise deux fois et que l'ordre des actions «succès» successeur ne peut être garanti?
@charlee pour plusieurs états de réussite, vous leur donnez simplement leurs propres noms, tels que loginSuccess, fetchUserSuccess, peu importe. Je stocke régulièrement l'état de redux dans mon composant.Ainsi, lorsque je reçois les mises à jour d'état de l'observable, je peux vérifier si l'état a changé ou non, si le succès est émis deux fois, il ne s'affiche qu'une seule fois.
@charlee si vous avez besoin de synchroniser plusieurs résultats avec un composant, je peux voir la possibilité de maintenir un tableau dans votre état qui a quelque chose comme {success: boolean, id: string} et de remplir id avec une valeur aléatoire ou unique. Je ne peux pas penser à trop de fois où cela serait nécessaire, mais il est possible d'avoir un état de redux de file d'attente.
Peut-être un peu en retard mais j'ai résolu un problème similaire en créant un petit module npm. Il vous permet de vous abonner et d'écouter les actions redux et exécute la fonction de rappel fournie dès que le changement d'état est terminé. L'utilisation est la suivante. Dans votre hook componentWillMount ou componentDidMount:
subscribeToWatcher(this,[
{
action:"SOME_ACTION",
callback:()=>{
console.log("Callback Working");
},
onStateChange:true
},
]);
Une documentation détaillée peut être trouvée à https://www.npmjs.com/package/redux-action-watcher
J'ai l'impression qu'un dialogue devrait être un effet secondaire, alors vous les mettriez dans des épopées
Comment faites-vous la navigation dans votre application? Utilisez-vous un routeur basé sur Redux comme
connected-react-router?@Harald Je ne veux pas que cette question soit trop précise. Je sais que si la route est stockée en tant qu'état redux, ce problème peut être résolu. Et si, disons, je veux simplement afficher une boîte de dialogue avec
window.alert ()après quelistTodo.success ()est observé?Ensuite, créez une nouvelle épopée qui surveille
listTodo.success (), effectuez un effet secondaire avecaction $ .tap (() => {window.alert ()}) code > puisignoreElements ()Merci @Harald. Puis-je faire cela (créer une épopée) dans un composant?
Vous devez utiliser
combineEpics ()pour combiner tous les Epics de votre application et l'exécuter avecepicMiddleware. Voir redux-observable.js.org/docs/basics/SettingUpTheMiddleware.h tml comment configurer correctementredux-observable@Harald J'ai commencé à comprendre votre première question. La route devrait probablement être un état global et la modification de la route n'est pas quelque chose dont un composant devrait s'inquiéter. J'essaie de déplacer plus de logiques dans Epics et de voir si je peux résoudre tous les problèmes.
Bonne chance! C'est un peu délicat au début, mais cela deviendra plus facile très rapidement. Et puis les épopées seront un bon moyen d'encapsuler la logique et de réduire l'état global.