est-il possible d'envoyer une action dans un réducteur lui-même? J'ai une barre de progression et un élément audio. L'objectif est de mettre à jour la barre de progression lorsque l'heure est mise à jour dans l'élément audio. Mais je ne sais pas où placer le gestionnaire d'événements ontimeupdate, ni comment envoyer une action dans le rappel de ontimeupdate, pour mettre à jour la barre de progression. Voici mon code:
//reducer
const initialState = {
audioElement: new AudioElement('test.mp3'),
progress: 0.0
}
initialState.audioElement.audio.ontimeupdate = () => {
console.log('progress', initialState.audioElement.currentTime/initialState.audioElement.duration);
//how to dispatch 'SET_PROGRESS_VALUE' now?
};
const audio = (state=initialState, action) => {
switch(action.type){
case 'SET_PROGRESS_VALUE':
return Object.assign({}, state, {progress: action.progress});
default: return state;
}
}
export default audio;
AudioElement
? Il semble que cela ne devrait pas être quelque chose en état.Réponses:
L'envoi d'une action dans un réducteur est un anti-motif . Votre réducteur doit être sans effets secondaires, il suffit de digérer la charge utile de l'action et de renvoyer un nouvel objet d'état. L'ajout d'écouteurs et la répartition des actions dans le réducteur peuvent entraîner des actions en chaîne et d'autres effets secondaires.
Des sons comme votre
AudioElement
classe initialisée et l'écouteur d'événements appartiennent à un composant plutôt qu'à l'état. Dans l'écouteur d'événements, vous pouvez envoyer une action, qui sera miseprogress
à jour dans l'état.Vous pouvez soit initialiser l'
AudioElement
objet classe dans un nouveau composant React, soit simplement convertir cette classe en composant React.Notez que le
updateProgressAction
est automatiquement entouré dedispatch
sorte que vous n'avez pas besoin d'appeler directement le dispatch.la source
MyAudioPlayer
composant à partir du conteneur parent qui estconnect
édité avecreact-redux
. Découvrez comment le fairemapDispatchToProps
ici: github.com/reactjs/react-redux/blob/master/docs/…updateProgressAction
défini dans votre exemple?redux-thunk
envoie une action à partir d'une autre action, pas le réducteur. stackoverflow.com/questions/35411423/…Démarrer une autre expédition avant la fin de votre réducteur est un anti-modèle , car l'état que vous avez reçu au début de votre réducteur ne sera plus l'état actuel de l'application lorsque votre réducteur aura terminé. Mais planifier un autre envoi depuis un réducteur n'est PAS un anti-modèle . En fait, c'est ce que fait le langage Elm, et comme vous le savez, Redux est une tentative d'amener l'architecture Elm en JavaScript.
Voici un middleware qui ajoutera la propriété
asyncDispatch
à toutes vos actions. Lorsque votre réducteur a terminé et renvoyé le nouvel état de l'application, ilasyncDispatch
se déclencherastore.dispatch
avec l'action que vous lui donnerez.Maintenant, votre réducteur peut le faire:
la source
dispatch
qui devraient renvoyer l'action. J'ai changé les dernières lignes en:const res = next(actionWithAsyncDispatch); syncActivityFinished = true; flushQueue(); return res;
et cela a très bien fonctionné.Vous pourriez essayer d'utiliser une bibliothèque comme redux-saga . Il permet un moyen très propre de séquencer les fonctions asynchrones, de déclencher des actions, d'utiliser des retards et plus encore. C'est très puissant!
la source
supplier
informations lorsque l'utilisateur tente de visiter laitem
page de détails. Par exemple, vouscomponentDidMount()
déclencheriez une fonction qui envoie une actionFETCH_SUPPLIER
. Dans le réducteur, vous pouvez cocher quelque chose comme unloading: true
pour montrer un spinner pendant la demande.redux-saga
écouterait cette action et, en réponse, lancerait la demande réelle. En utilisant les fonctions du générateur, il peut alors attendre la réponse et la viderFETCH_SUPPLIER_SUCCEEDED
. Le réducteur met ensuite à jour le magasin avec les informations du fournisseur.redux-loop s'inspire d'Elm et fournit ce modèle.
la source