title: Routing based on Async Authentication check using React-router
body: <p>So have followed the answers in <a href="https://stackoverflow.com/questions/46162278/authenticate-async-with-react-router-v4">this question</a> to do a router based on whether the user is authenticated or not.</p>
  
  <p>My route looks like this (this is an Authentication only App)-</p>
  
  <pre><code>"/" -&gt; Login
   |
   |
   |- "/home" -&gt; User Home page based on some criteria of the logged in user
   |
   |- "/catalog" -&gt; Catalog page based on some criteria of the logged in user
  </code></pre>
  
  <p>In short, the <code>/home</code> and <code>/catalog</code> are protected routes and only authenticated users are allowed. All non authenticated users must be routed to root i.e. <code>"/"</code> which is the login page. The authentication check function is Async so I have my index.js and App.js something like this-</p>
  
  <p>index.js</p>
  
  <pre><code>import PrivateRoute from './App';
  
  &lt;BrowserRouter&gt;
    &lt;div&gt;
      &lt;Switch&gt;
        &lt;PrivateRoute path="/home" component={Client}/&gt;
        &lt;PrivateRoute path="/catalog" component={Catalog}/&gt;
        &lt;PrivateRoute path="/" component={Landing}/&gt;
      &lt;/Switch&gt;
    &lt;/div&gt;
  &lt;/BrowserRouter&gt;
  </code></pre>
  
  <p>App.js</p>
  
  <pre><code>class App extends Component {
    state = {
      loading: true,
      isAuthenticated: false,
      role: ''
    };
  
    componentDidMount() {
      getUserSession((isValid,session,err) =&gt; {
        if (isValid){
          console.log('is Valid Session');
          this.setState({
            loading: false,
            isAuthenticated: isValid,
          });
        }else if (err){
          console.log('is InValid Session');
          this.setState({
            loading: false,
          });
        }
      });
    }
  
    render() {
      const { component: Component, ...rest } = this.props
      console.log(this.props);
      return (
        &lt;Route
          {...rest}
          render={props =&gt;
            this.state.isAuthenticated ? (
              &lt;Component {...props} /&gt;
            ) : (
                this.state.loading ? (
                  &lt;div&gt;LOADING&lt;/div&gt;
                ) : (
                    &lt;Redirect to={{ pathname: '/', state: { from: this.props.location } }} /&gt;
                  )
              )
          }
        /&gt;
      )
    }
  }
  </code></pre>
  
  <p>It's worth noting that I am not using Redux for grabbing the Authentication state of the user, instead using AWS Amplify method calls to simply get the user session. The <code>getUserSession</code> function returns whether a user session is Valid and some additional information like the session object etc. </p>
  
  <p>I have 2 issues -</p>
  
  <ol>
  <li><p>When an un-authenticated user comes in, the redirect is causing an infinite loop since <code>"/"</code> goes through the authentication check again and again via the <code>Redirect</code> causing an <code>Maximum update depth exceeded</code> error because of <code>setState</code> call in App.js.</p></li>
  <li><p>If a user is authenticated then they end up in the <code>&lt;Component {...props} /&gt;</code> line in App.js. This is ok as long as the user is hitting the specific <code>/home</code> or <code>/catalog</code> routes. However, if the user is authenticated and hits the root route <code>/</code> i would want them to re-direct them to one of either <code>/home</code> or <code>/catlog</code> routes and I am simply not getting how to do that.</p></li>
  </ol>
  
  <p>Any insights would be greatly appreciated.</p>