J'utilise redux avec connect
et redux-thunk
middleware et conteneurs.
Actuellement, lorsqu'un utilisateur exécute une action, par exemple un clic sur un bouton, je dois envoyer cette action (sync) qui distribuera d'autres actions (asynchrone).
Je suis conscient que l'envoi d'actions à l'intérieur du réducteur est un modèle anti-modèle.
Je voudrais savoir quel est l'endroit approprié pour ce code.
Actuellement, je ne sais pas si cela devrait rester dans:
La manière recommandée selon documentation se trouve dans le créateur de l'action, comme suit:
function actionCreator(payload) {
return dispatch => {
dispatch(action1(payload))
dispatch(action2(payload))
}
}
Ensuite, vous voudrez probablement attacher les créateurs d’action en tant que prop et les transmettre au conteneur en utilisant mapDispatchToProps
comme dans l’exemple mentionné ici . Donc, cela ressemblerait à quelque chose comme ça:
const mapDispatchToProps = dispatch => ({
action1: some_payload => dispatch(action1(some_payload))
action2: some_payload => dispatch(action2(some_payload))
})
// your component
export default connect(mapStateToProps, mapDispatchToProps)(YourApp)
Comme d'autres l'ont souligné, The action creator
Est le bon endroit pour envoyer plusieurs actions.
Ci-dessous, un exemple de la façon dont action1
Pourrait envoyer d'autres actions dans votre action creator
.
const action1 = id => {
return dispatch => {
dispatch(action2(id))
dispatch(action3(id))
}
}
Le créateur d'action est l'emplacement correct pour la distribution de plusieurs actions. Bien que du code comme celui-ci fonctionne:
function actionCreator(payload) {
return dispatch => {
dispatch(action1(payload))
dispatch(action2(payload))
}
}
Je recommanderais vivement aux créateurs d'action basés sur redux-thunk
De toujours renvoyer une promesse résolue, afin que ces créateurs d'action puissent faire partie d'un autre appel asynchrone. Ainsi, la mise à jour la plus simple de ce qui précède serait:
function actionCreator(payload) {
return dispatch => {
dispatch(action1(payload));
dispatch(action2(payload));
return Promise.resolve();
}
}
Il serait alors possible d’envoyer à ce qui précède avec: actionCreator(payload).then(doAnotherAction(anotherPayload))
ou le suivant, si nous devons conserver l’ordre des appels: actionCreator(payload).then(() => doAnotherAction(anotherPayload))
Si vous souhaitez "pérenniser" votre créateur d'action afin qu'il puisse gérer l'appel des créateurs d'actions asynchrones et synchronisés, vous pouvez l'écrire comme suit:
function actionCreator(payload) {
return dispatch =>
Promise.resolve(dispatch(action1(payload))).then(
() => dispatch(action2(payload)));
}
Et si vous aimez la notation de flèche ES6, vous pouvez définir ce qui suit:
const actionCreator = payload => dispatch =>
Promise.resolve(dispatch(action1(payload))).then(
() => dispatch(action2(payload)));
Bien que la solution de @GibboK ne fonctionne pas pour moi:
const mapDispatchToProps = (dispatch) => ({
action2: id => dispatch(Actions.action2(id)),
action3: id => dispatch(Actions.action3(id)),
action1: (dateId, attrId) => {
return dispatch => {
dispatch(Actions.action2(dateId));
dispatch(Actions.action3(attrId));
}
}
});
Je suis finalement allé avec redux-batched-actions . A travaillé comme un charme:
const mapDispatchToProps = (dispatch) => ({
action2: id => dispatch(Actions.action2(id)),
action3: id => dispatch(Actions.action3(id)),
action1: (dateId, attrId) =>
dispatch(batchActions([
Actions.action2(dateId),
Actions.action3(attrId)
]))
});
Si vous avez un Promise Middleware , vous pouvez utiliser cette syntaxe pour pouvoir utiliser .then()
sur votre dispatch(topLevelAction())
:
export const topLevelAction = () => dispatch => {
return Promise.all([dispatch(action1()), dispatch(action2()), dispatch(action3())])
}