Router: redirectTo not redirect and throw error

Created on 17 Jul 2018  路  29Comments  路  Source: reach/router

in App i try redirect to login page anon user

componentDidMount() {
    const { isAuthenticated } = this.props;
    if (!isAuthenticated) redirectTo('/login');
  }

in console i have

 Uncaught RedirectRequest聽{uri: "/login"}
The above error occurred in the <App> component:
    in App (created by Connect(App))
    in Connect(App)
    in MuiThemeProvider
    in Provider

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

How to use redirect right and fix this

Most helpful comment

Throwing an error on redirect is intended behavior, and explained in the docs:

https://reach.tech/router/api/Redirect

Redirect works with componentDidCatch to prevent the tree from rendering and starts over with a new location.

Because React doesn鈥檛 swallow the error this might bother you. For example, a redirect will trigger Create React App鈥檚 error overlay. In production, everything is fine. If it bothers you, add noThrow and Redirect will do redirect without using componentDidCatch.

If you鈥檙e using React < 16 Redirect will not throw at all, regardless of what value you put for this prop.

If you鈥檙e using componentDidCatch in your app please read the isRedirect doc!

noThrow

<Redirect noThrow />

All 29 comments

Possibly related to #91.

I'm having the same issue & I'm also using <Redirect to="/login" /> route like

render() {
  if (!isAuthenticated) return <Redirect to="/login" />;
}

Also, I have HMR enabled & whenever I refresh the above file, my Electron app gives an error Cannot GET /

How to solve this same issue? /cc @ryanflorence

I have made a CodeSandBox for this issue. Just run the Sandbox & wait for 3 seconds & it will throw error. This is the error that I want to remove known as the error 馃槣

Also having this same issue @ryanflorence

I switched to react-router. Although this API is much easier, few things like Hash Router won't be supported & the workaround has lot of code & there will be few errors as its in its early stages. So I switched. You can if you want to. It won't require a lot of code to switch other than 4-5 lines extra till this thing gets solved.

@deadcoder0904 i fixed it with navigate() !isAuthenticated && navigate('/login');

Nice. But I already switched because I needed Hash Router & the workaround for @reach/router to use Hash includes lot of code than React Router.

But anyways next time I'll use this one. The API is so cool 馃槏

@Popugune Unfortunately navigate() has the same issue for me.

@deadcoder0904 I can't switch to React Router as I'm using Gatsby v2 which uses Reach Router internally.

@chasemccoy Use a earlier beta version of Gatsby v2 which uses React Router. I think its only recently introduced. I am using v0.0.0-beta.61 if you want to try it out :)

I want to stay on the latest version.

Using latest gatsby v2 as well. Ive had to create a Redirect component with timeout:

class Redirect extends Component {
  static propTypes = {
    to: PropTypes.string.isRequired,
    navigate: PropTypes.func.isRequired,
  };

  componentDidMount() {
    setTimeout(() => this.props.navigate(this.props.to, { replace: true }), 0);
  }

  render() {
    return null;
  }
}

I would still like to get <Redirect> to work as expected

Right now I get Uncaught RedirectRequest聽{uri: "/login"}

Authenticated HOC

import React from 'react';
import PropTypes from 'prop-types';
import { Redirect } from '@reach/router';

class Authenticated extends React.Component {
  render() {
    const { authenticated, children } = this.props;

    return authenticated ? <React.Fragment>{children}</React.Fragment> : <Redirect to="/login" />;
  }
}

Authenticated.propTypes = {
  children: PropTypes.node.isRequired,
  authenticated: PropTypes.bool.isRequired,
};

export default Authenticated;

Router

<Router>
  <Authenticated path="profile" {...props}>
    <Profile path="/" {...props} />
    <NotFound default />
  </Authenticated>
</Router>

The page actually redirects but the error is there.

@416serg you solution look like good

Throwing an error on redirect is intended behavior, and explained in the docs:

https://reach.tech/router/api/Redirect

Redirect works with componentDidCatch to prevent the tree from rendering and starts over with a new location.

Because React doesn鈥檛 swallow the error this might bother you. For example, a redirect will trigger Create React App鈥檚 error overlay. In production, everything is fine. If it bothers you, add noThrow and Redirect will do redirect without using componentDidCatch.

If you鈥檙e using React < 16 Redirect will not throw at all, regardless of what value you put for this prop.

If you鈥檙e using componentDidCatch in your app please read the isRedirect doc!

noThrow

<Redirect noThrow />

@cdock1029 I was having this issue even when using the noThrow prop, but I will double check that again.

@chasemccoy issue as defined doesn't specify "with gatsby" and it seems that's where this error manifests (at least for some in this thread) OP might want to clarify that.

Without gatsby, is there no issue? Might want to cross post this on gatsby repo.

@deadcoder0904 some minor tweaks to your codesandbox for clarity.. but it's working fine. Add noThrow if you don't want to see the error, but the error will not exist in prod.

@ryanflorence look please

hey, so the issue is still there. any solutions?

If you are doing a redirect (for a login page) use:
<Redirect from="" to="" noThrow />

Alternatively use navigate('')

The Gatsby examples need to be updated.

Having this issue on a fresh create-react-app install as well.

I tried <Redirect to="/" /> as well as redirectTo(), the only way it works is with setTimeout(..., 0).

Well, I read the above comments. Not really sure how to use redirectTo in a way that it does not throw & actually redirects.

The redirectTo doc does not help. Also, the doc says uri must be absolute, but the example uses a relative path. 馃槙

Like @detj I find redirectTo doc to have zero guidance on how to make this work. I ended up using navigate (import { navigate } from "@reach/router"; ) as a workaround.

I used navigate as a workaround too.

For anyone struggling about how to write tests against Redirect w/o throwing errors, I hope this helps you:

import React from 'react'
import { wait } from 'utils/test'
import renderWithRouter, {
    RenderWithRouterOptions,
} from 'utils/test/renderWithRouter'

it('redirects from "/" to "/foo"', async () => {
    const spy = jest.spyOn(console, 'error').mockImplementation(() => {})

    renderWithRouter(<Routes />, { route: '/' })

    await wait(() => {
        expect(document.title).toBe('Foo')
    })

    spy.mockRestore()
})

See renderWithRouter here and refer to Testing Library | Reach Router example.

As mentioned, <Redirect from="" to="" noThrow /> will solves for the error being thrown 馃槉

redirectTo throws error and doesn't navigate with ErrorBoundary even. The error is caught but that doesn't help, everything is unmounted anyway.

Thank you @cdock1029 .
I have the following in my login.js file

  // redirect if authenticated.
  if (isAuthenticated) return <Redirect to="/app" noThrow />;

adding noThrow doesn't cause app to crash after the user login and redirect to the app page

very declarative

We had a similar issue only we had issues using the Redirect component as well as the navigate and redirectTofunctions when sending from a reach routed component to a static page on gatsby.

The solution was to just use window.location inside of an effect hook. It looked similar to this:

  const [shouldRedirect, setShouldRedirect] = useState();
  const [linkTo, setLinkTo] = useState("/some/location");
  const handleClick = () => {
    setShouldRedirect(true);
  };

  useEffect(() => {
    if (shouldRedirect && linkTo) {
      window.location.replace(linkTo);
    }
  }, [shouldRedirect]);

Was this page helpful?
0 / 5 - 0 ratings

Related issues

magnusarinell picture magnusarinell  路  3Comments

jsonmaur picture jsonmaur  路  4Comments

alexandernanberg picture alexandernanberg  路  3Comments

EJIqpEP picture EJIqpEP  路  4Comments

artoodeeto picture artoodeeto  路  4Comments