How to achieve callbacks in Redux-Saga?

我与影子孤独终老i 提交于 2019-11-30 00:38:17

问题


The scenario is, I want to redirect a user or show alert based on the success, error callbacks after dispatching an action.

Below is the code using redux-thunk for the task

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

because the dispatch action in redux-thunk returns a Promise, It is easy to act with the response.

But now I'm getting my hands dirty on redux-saga, and trying to figure out how I can achieve the same result as above code. since Saga's run on a different thread, there is no way I can get the callback from the query above. so I just wanted to know how you guys do it. or whats the best way to deal with callbacks while using redux-saga ? the dispatch action looks like this :

this.props.actions.login(credentials);

and the 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})
  }
}

saga monitor

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

action creator

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

回答1:


I think you should add redirect and alert to the login generator. This way all logic is in the saga and it is still easily tested. So basically your login saga would look like this:

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
  }
}



回答2:


I spent all day dinking around with this stuff, switching from thunk to redux-saga

I too have a lot of code that looks like this

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

its possible to use thunk + saga

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

then over in saga land you can just do something like

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



回答3:


You can simply work up by passing the extra info about your success and error callback functions into the payload itself. Since, redux pattern works in a quite decoupled manner.

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

In the saga, you can deconstruct these callbacks from the payload and run them very easily based on your program flow.



来源:https://stackoverflow.com/questions/41076600/how-to-achieve-callbacks-in-redux-saga

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!