web-dev-qa-db-fra.com

Comment réaliser des rappels dans Redux-Saga?

Le scénario est, je veux rediriger un utilisateur ou afficher une alerte en fonction du succès, des rappels d'erreur après l'envoi d'une action.

Ci-dessous le code utilisant redux-thunk pour la tâche

this.props.actions.login(credentials)
.then((success)=>redirectToHomePage)
.catch((error)=>alertError);

parce que l'action de répartition dans redux-thunk renvoie une promesse, il est facile d'agir avec la réponse.

Mais maintenant, je me salis les mains sur redux-saga et j'essaie de comprendre comment je peux obtenir le même résultat que le code ci-dessus. depuis l'exécution de Saga sur un thread différent, il n'y a aucun moyen que je puisse obtenir le rappel de la requête ci-dessus. donc je voulais juste savoir comment vous le faites. ou quelle est la meilleure façon de gérer les rappels lors de l'utilisation de redux-saga? l'action de répartition ressemble à ceci:

this.props.actions.login (informations d'identification);

et la saga

function* login(action) {
  try {
    const state = yield select();
    const token = state.authReducer.token;
    const response = yield call(API.login,action.params,token);
    yield put({type: ACTION_TYPES.LOGIN_SUCCESS, payload:response.data});
    yield call(setItem,AUTH_STORAGE_KEY,response.data.api_token);
  } catch (error) {
    yield put({type: ACTION_TYPES.LOGIN_FAILURE, error})
  }
}

moniteur de saga

export function* loginMonitor() {
  yield takeLatest(ACTION_TYPES.LOGIN_REQUEST,login);
}

créateur d'action

function login(params) {
  return {
    type: ACTION_TYPES.LOGIN_REQUEST,
    params
  }
}
19
ZaL

Je pense que vous devriez ajouter une redirection et une alerte au générateur de connexion. De cette façon, toute la logique est dans la saga et elle est toujours facilement testée. Donc, fondamentalement, votre saga de connexion ressemblerait à ceci:

function* login(action) {
  try {
    const state = yield select();
    const token = state.authReducer.token;
    const response = yield call(API.login,action.params,token);
    yield put({type: ACTION_TYPES.LOGIN_SUCCESS, payload:response.data});
    yield call(setItem,AUTH_STORAGE_KEY,response.data.api_token);
    yield call(redirectToHomePage); // add this...
  } catch (error) {
    yield put({type: ACTION_TYPES.LOGIN_FAILURE, error});
    yield call(alertError); // and this
  }
}
6
Henrik R

J'ai passé toute la journée à réfléchir avec ce genre de choses, passant de thunk à redux-saga

Moi aussi, j'ai beaucoup de code qui ressemble à ceci

this.props.actions.login(credentials)
.then((success)=>redirectToHomePage)
.catch((error)=>alertError);

il est possible d'utiliser thunk + saga

function login(params) {
  return (dispatch) => {
    return new Promise((resolve, reject) => {
      dispatch({
        type: ACTION_TYPES.LOGIN_REQUEST,
        params,
        resolve, 
        reject
      })
    }
  }
}

puis dans le pays de la saga, vous pouvez simplement faire quelque chose comme

function* login(action) {
  let response = yourApi.request('http://www.urthing.com/login')
  if (response.success) {
    action.resolve(response.success) // or whatever
  } else { action.reject() }
}
11
James

Vous pouvez simplement travailler en passant les informations supplémentaires sur vos fonctions de rappel de réussite et d'erreur dans la charge utile elle-même. Depuis, le modèle de redux fonctionne de manière assez découplée.

this.props.actions.login({
   credentials,
   successCb: success => redirectToHomePage)
   errorCb: error => alertError)
 });

Dans la saga, vous pouvez déconstruire ces rappels de la charge utile et les exécuter très facilement en fonction de votre flux de programme.

0
Param Singh