How do I add redirect to react-router dynamically?

stkvtflw picture stkvtflw · Sep 27, 2015 · Viewed 21.1k times · Source

I have sign in component, which should be available for unauthenticated users. And right after the authentication this component should become unavailable.

   var routes = (
      <Route handler={App}>
        <Route name="signIn" handler={signIn}/>
        {/* redirect, if user is already authenticated */}
        { localStorage.userToken ? (
            <Redirect from="signIn" to="/user"/>
          ) : null
        }
      </Route>
    );

Router.run(routes, (Handler, state) => {
  React.render(<Handler {...state}/>, document.getElementById('main'));
});

This code works perfect if user have reloaded webapp for any reason after the authentication, but of course it doesn't if user didn't reload the webapp. I've tried to use this.context.router.transitionTo right to the SignUp component, but it works awful - the component gets rendered, then this script is getting executed.

So I want to add the redirect right into the routes variable to make the router redirect without even trying to render the component.

Answer

trekforever picture trekforever · Sep 27, 2015

Instead of checking your auth-flow and conditionally rendering particular routes, I would recommend another approach:

If you're using react-router 0.13.x, I would recommend using the willTransitionTo methods on your components when you need to check authentication. It is called when a handler is about to render, giving you the opportunity to abort or redirect the transition (in this case, check if user is authenticated, redirect to another path if not). See auth-flow example here: https://github.com/ReactTraining/react-router/blob/v0.13.6/examples/auth-flow/app.js

For versions >0.13.x, it would be onEnter and Enterhooks. See the auth-flow example here: https://github.com/rackt/react-router/blob/master/examples/auth-flow/app.js

Basically you move the auth-check flow away from your routes variable, and into transition events/hooks. Before the route handler actually gets rendered, check the auth, and redirect the user to another route.