Search code examples
reactjsreduxredux-thunk

Cancelling previous async action using redux-thunk


I am building a React/Redux app using the redux-thunk middleware to create and handle Ajax requests. I have a particular thunk that is fired pretty often, and I would like to cancel any previously started Ajax requests before firing a new one. Is this possible?


Solution

  • One approach would be to mark those requests as canceled by giving them random id and checking its status before handling the result.

    The way to do this is to assign random id for this call in your first dispatch (inside the thunk) and check it in the reducer before handling the result.

    const actionId = Math.random();
    dispatch({type: AJAX_LOAD_CONST, id:actionId })
    

    When you want to cancel all of the request use

    dispatch({type:HANDLE_AJAX_RESPONSE, id:actionId, results: json })

    When you want to handle the results don't forget to send the id that you u

    and in the reducer have something like this:

    function reducer(state = initialState, action) {
      switch (action.type) {
        case actions.AJAX_LOAD_CONST:
          return Object.assign({}, state, { ajax: state.ajax.concat(action.id) });
        case actions.CANCEL_ALL_AJAX:
          return Object.assign({}, state, { ajax: [] });
        case actions.HANDLE_AJAX_RESPONSE:
          if (state.ajax.includes(action.id) {
            //return state reduced with action.results here
          }
          return state;
      }
    }
    

    If you use XMLHttpRequest or one of it's wrappers (JQuery?) you can also store the requests themselves and call request.abort(). if you use the new fetch api you do not have this luxury as promises lack this behavior.