ketysek
ketysek

Reputation: 1219

React router - page doesn't change when navigating from outside component

I'm trying to redirect user to "Not Authorized" page after there's 403 api response. Here's what I got so far:

created my own history for using history.push outside React components

import { BrowserRouter } from "react-router-dom"
import { createBrowserHistory } from "history"

export const history = createBrowserHistory()

export default class OwnBrowserRouter extends BrowserRouter {
  history
}

Then I got an api handler like this:

import { history } from "./my-own-history"

const responseErrorHandler = error => {
  const status = _get(error, "response.status")
  if (status === 403) {
    history.push(getRoutePath("not-authorized"))
  }

  throw error
}

const requestFactory = (
  method,
  url,
  body = {},
  useToken = true,
  ownToken = ""
) => {
  ... not important code here ...

  return axios(url, config)
    .then(responseSuccessHandler)
    .catch(responseErrorHandler)
}

And at last I have an Article page, where I'm calling redux action retrieveArticle(id). If the user is not authorized to see the article, the browser's route is changed to /not-authorized correctly, but the Article component stays rendered (page doesn't change). When I add .then(() => this.props.history.push("/not-authorized")) to the redux action call, it started to work, but I don't want to add this to every api call in my app ... I want to solve it globally for all api calls in my api handler.

Upvotes: 1

Views: 242

Answers (1)

Michal
Michal

Reputation: 447

Change

export default class OwnBrowserRouter extends BrowserRouter {
  history
}

To

export default class OwnBrowserRouter extends BrowserRouter {
  history = history;
}

As stated in the Class fields proposal, certain transpilers may ignore the field completely. Thus the original history (the one created in the original BrowserRouter) will be used.

Both public and private field declarations create a field in the instance, whether or not there's an initializer present. If there's no initializer, the field is set to undefined. This differs a bit from certain transpiler implementations, which would just entirely ignore a field declaration which has no initializer.

Upvotes: 1

Related Questions