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 trialMike Lundahl
13,510 PointsReact 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
19,465 PointsHi 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.