0

I am using react with redux. In the redux layer I am using thunk. So component calls action, redux action calls a new layer -> service. The service handles http calls. When response is ok - I use the dispatch that thunk provides and return to the reducer. when the response is error I want to redirect the user and I couldn't find a way to do so. I am missing the router and its replace method.

user1235003
  • 91
  • 1
  • 4
  • 2
    Possible Duplicate of [use-history-push-in-action-creator-with-react-router-v4](https://stackoverflow.com/questions/48514773/use-history-push-in-action-creator-with-react-router-v4/48514877#48514877) – Shubham Khatri Mar 06 '18 at 18:56

3 Answers3

0

You could catch inside the component which triggered the action creator

function doAction() {
  return (dispatch) => {
    return fetch(...).then(...)
  }
}

class Component extends React.Component {
  onClickButton = () => {
    this.props.doAction().catch(() => {
      this.props.router.replace(...)
    })
  }
}

I'm assuming you've connected properly and router is being passed in as a prop (or a context - doesn't really matter so long as it's available in the component)

one downside to this is that you have to replicate this functionality whenever you use that action creator. You could provide the router as an argument to the action creator, but I'm not sure if that's against standard practice/an anti-pattern.

Another option is to hard-redirect using window.location

Tyler Sebastian
  • 9,067
  • 6
  • 39
  • 62
0

Ok, I think I've got it. I created a general redux action called ResponseError. I will dispatch this action in all my services, every time an HTTP call returns with error. Then in the reducer I'll just turn on a boolean flag on the store and in the main application page I'll listen to this flag. If it is on -> do whatever you want.

user1235003
  • 91
  • 1
  • 4
  • I believe whatever service you are using to make the HTTP call should have some form of middleware or interceptor which you can place your logic there to handle any generic error. See my answer https://stackoverflow.com/a/49142188/2617503 for example. – Mosufy Mar 07 '18 at 00:26
0

If you are using axios for the service that handles http calls, you can use its interceptor. This way, you do not need to have a handler on every action/reducer-action.

import axios from 'axios';

axios.interceptors.response.use(
  res => interceptResponse(res), 
  err => interceptError(err)
);

const interceptResponse = response => {
  // nothing to do here, return back response
  return response;
};

const interceptError = error => {
  if (error.response.status === 404 || error.response.status === 403) {
    // redirect to another react router page 
    history.push('/error404');
  } else if (error.response.status === 401) {
    return Promise.reject(error);
  }
};

Referenced from my sample project on GitHub: https://github.com/mosufy/serverless-react/blob/develop/client/site/src/lib/sdk.js#L90

Mosufy
  • 151
  • 3