简体   繁体   中英

what will be best Approach for Redux-thunk Async Request to handle onSuccess and onError?

what should be the best approach to manage Redux-Thunk async requests. like I'm posting some data on server and the connected component will check the errors by

Approach 1: I just return new Promise in my action creators to check resolve or reject by using then

const update = (todoId, isDone) => (dispatch) =>
new Promise(function(resolve, reject) {
dispatch({
  type: 'SET_SAVING',
  saving: true
});
// Function is expected to return a promise
callUpdateApi(todoId, isDone).then(updatedTodo => {
  dispatch({
    type: 'SET_SAVING',
    saving: false
  });

  resolve(updatedTodo);
}).catch(error => {
  // TBD: Handle errors for Redux

  reject(error);
})
});

Approach 2: using dispatch to manage error in render method by if-else conditions

const update = (todoId, isDone) => (dispatch) => {
dispatch({
    type: 'SET_SAVING',
    saving: true
  });
  // Function is expected to return a promise
  callUpdateApi(todoId, isDone).then(updatedTodo => {
    dispatch({
      type: 'SET_SAVING',
      saving: false
    });
  });
  // TBD: Handle errors
}

please help me find the best solution for this should I go with "return Promise" from Action creators or just using the dispatch actions to store for error and success handling always. because onsuccess I need to do some stuff in my component and on error also

const update = (todoId, isDone) => (dispatch) =>
new Promise(function(resolve, reject) {
dispatch({
  type: 'SET_SAVING',
  saving: true
});
// Function is expected to return a promise
callUpdateApi(todoId, isDone).then(updatedTodo => {
  dispatch({
    type: 'SET_SAVING',
    saving: false
  });

  resolve(updatedTodo);
}).catch(error => {
  // TBD: Handle errors for Redux

  reject(error);
})
});

If your callUpdateApi returns a promise you don't have to wrap your whole action in a promise, just can just return callUpdateApi . As for error handling, the common way is to set a flag somewhere in your redux state along with the saving flag for example to know when an error occured. Your components will then receive those flags and do something with them

const update = (todoId, isDone) => (dispatch) => {
  dispatch({
    type: 'SET_SAVING',
    saving: true
  });

  return callUpdateToApi(todoId, isDone).then(updatedTodo => {
    dispatch({
      type: 'SET_SAVING',
      saving: false,

      // Do something with your API response
      // e.g. update your redux store via a reducer
      updatedTodo
    });
  })
  .catch(err => {
    // Handle error, for example set a error flag
    // in your redux state so your components know an error occured
     dispatch({
      type: 'SET_SAVING',
      saving: false,
      error: true
    });
  });
}

Connect your component so that they can access error and saving flags and for example display an error when your call failed:

export default connect(
  state => ({
    error: state.module.error,
    saving: state.module.saving
  })
)(Component);
// Inside your JSX
{this.props.error && <p>An error occured</p>}

the best practice we use is each thunk action dispatched 3 actions:

  1. action started
  2. action succeeded
  3. action failed

callUpdateApi is a promise then just return it in your thunk like this:

const update = (params) => (dispatch) => {
  dispatch(started())
  return callUpdateApi(params)
    .then(result => dispatch(succeeded(result)))
    .catch(error => dispatch(failed(error)))
}

and inside the reducer you can toggle the saving flag for started set it to true and for succeeded or failed set it to false that's it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM