web-dev-qa-db-fra.com

Où envoyer plusieurs actions dans Redux?

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:

  • Le créateur d'action.
  • Dans le conteneur en utilisant store.subscribe.
24
Radex

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)

21
Mμ.

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))
  }
}
15
GibboK

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)));
4
Shiraz

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)
    ]))
});
2
Bugs Bunny

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())])
}
0
RubbelDieKatz