Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Mike Lundahl
Mike Lundahl
13,510 Points

React redirect to component

Hi all,

I'm a little bit stuck trying to figure this out for my web app.

So I have a log in page which I want the user to be redirected to a welcome page when signing in. Using NavLink with react router works well but I want to run it through a component that will authenticate the user & password from my mongoDB and if successfull redirect the user to the welcome screen. Can't get it to work. I get the URL in the adress field but it wont render the screen. Any ideas what I'm doing wrong?

Here's the code

App.js

import React, { Component } from 'react';
import {render} from 'react-dom';
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
import { Redirect } from 'react-router-dom';
import createHistory from 'history/createBrowserHistory';

import HeaderWrap from './Header';
import Login from '../components/login/Login'
import Welcome from '../components/welcome/Welcome'
import Footer from '../components/footer/Footer'

export default class App extends Component {

    constructor(props) {
        super(props);

        this.state = {
                    signIn: false,
                  }
            };

        this.handleSubmit = this.handleSubmit.bind(this);
        }

handleSubmit() {

    const history = createHistory();

    history.push('/welcome');
}

render() {

         return (

    <div>
        <div id="mainWrapper">

              <Router history={history} >
                <div>
                    <Route render={ (props) => (<HeaderWrap userData={userData} logout={this.logout} />)} />
                    <Route exact={true} path="/" render={ (props) => (<Calculator userData={userData} />)} />
                    <Route path="/*" component={NotFound} />
                    <Route path="/login" render={ (props) => (<Login submit={this.handleSubmit} />)} />
                    <Route path="/welcome" render={ (props) => (<Welcome userData={userData} />)}/>
                    <Route component={Footer} />
                </div>
            </Router>
        </div>
        </div>
        )

    };

The login component

import React, { Component, PropTypes } from 'react';
import { BrowserRouter as Router, Route, NavLink  } from 'react-router-dom';
import { Redirect, Link } from 'react-router-dom';
import createHistory from 'history/createBrowserHistory';

export default class Login extends Component {

    constructor(props) {
        super(props);

        this.state = {
            signIn: false,
        };

render() {

        return (
            <div className="normalContentWrapper">
                    <div id="login">
                        <p id="login-section">
                            <div className="btn" onClick={this.props.submit.bind(this)} >Log In!</div>
                        </p>
                    </div>
        );
    };

1 Answer

Angelica Hart Lindh
Angelica Hart Lindh
19,465 Points

Hi Mike,

A bit late on the answer here, but for your interest and others who have the same issue below is an example.

The example sets up an array of routes within a react-router switch and makes use of the <Route/>, <Redirect/> and the <PrivateRoute/> HOC that is used to validate the user is authenticated. When a user is not authenticated in the app they are redirected to the Login screen.

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';

// Private Route HOC 
const PrivateRoute = ({ component, exact = false, path, authenticated }) => (
   <Route
      exact={exact}
      path={path}
      render={props =>
         authenticated ? (
            React.createElement(component, props)
         ) : (
               <Redirect
                  key="login"
                  to={'/login'}
               />
            )
      }
   />
)

// Login Page
class Login extends Component {

   // Handle Login .... fake example
   login = () => {
      // Call onLogin prop after 1s
      setTimeout(() => this.props.onLogin, 1000)
   }

   render() {
      return (
         <div><button onClick={this.login}>Login</button></div>
      )
   }

}

// Private Welcome Page
const Welcome = () => <div>Private Page</div>



class Routing extends Component {
   state = { loggedIn: false }

   handleLogin = () => {
      this.setState({ loggedIn: true })
   }

   routes() {
      const { loggedIn } = this.state
      const routeArr = [
         <Route
            exact
            path="/"
            component={() =>
               loggedIn ? (
                  <Redirect to="/welcomuser" />
               ) : (
                     <Redirect to="/login" />
                  )}
         />,
         <PrivateRoute
            authenticated={loggedIn}
            key="main"
            path="/welcomeuser"
            component={Welcome}
         />,
         <Route key="login" exact path="/login" component={() => <Login onLogin={this.handleLogin} />} />,
         <Route component={NotFound} />,
      ];

      if (!loggedIn) {
         routeArr.push(<Redirect key="loginRedirect" to="/login" />);
      }

      return routeArr;
   }

   render() {
      return (
         <Router>
            <Switch>{this.routes()}</Switch>
         </Router>
      )
   }
}


const App = () => (
   <div>
      <Routing />
   </div>
)

This is how I have handled auth using <Switch/> from react-router. There is other ways to achieve the same as mentioned in the react router documentation https://reacttraining.com/react-router/web/example/auth-workflow. The example in the documentation however doesn't make use of the Switch component.