Redirecting to login page with react-router v4
I am new to React.
I want to create an amdin app that redirects login by default (main menu is hidden). Using react-router v4 based on this sample the menu is already shown by default. What's the best practice? Here is my current code
in index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {
BrowserRouter,
Route,
Switch
} from 'react-router-dom';
import createHistory from 'history/createBrowserHistory'
import registerServiceWorker from './registerServiceWorker';
import './index.css';
import App from './App';
import Login from './modules/Login';
ReactDOM.render((
<BrowserRouter history={createHistory}>
<Switch>
<Route path="/login" component={Login} />
<Route path="/" component={App} />
</Switch>
</BrowserRouter>
), document.getElementById('root'));
registerServiceWorker();
in app.js
import React from 'react'
import {
BrowserRouter,
Link,
Switch,
Route,
Redirect
} from 'react-router-dom'
import { routes } from './router-config'
import Login from './modules/Login'
import fakeAuth from './Auth'
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route
{...rest} render={props => (
fakeAuth.isAuthenticated ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}} />
)
)} />
);
const App = () => (
<BrowserRouter>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/protected">Protected</Link></li>
</ul>
<Switch>
{routes.map((route,index) => (
<PrivateRoute key={index} path={route.pattern} component={route.component} exact={route.exactly} />
))}
</Switch>
</div>
</BrowserRouter>
)
export default App
in login.js
import React, { Component } from 'react'
import {
Redirect
} from 'react-router-dom'
import fakeAuth from '../Auth'
import App from '../App'
class Login extends Component {
state = {
redirectToReferrer: false
}
login = () => {
fakeAuth.authenticate(() => {
this.setState({ redirectToReferrer: true })
})
}
render() {
const { from } = this.props.location.state || { from: { pathname: '/' } }
const { redirectToReferrer } = this.state
if (fakeAuth.isAuthenticated) {
return (
<Redirect to={"/"}/>
)
}
return (
<div>
<p>You must log in to view the page at {from.pathname}</p>
<button onClick={this.login}>Log in</button>
</div>
)
}
}
export default Login;
I can click login and redirect the app, but when I refresh the page in the app, the url is changed to / login, but the display is still in the app. Please help. Many thanks
+3
source to share
1 answer
I solved this problem by creating a component and loading it in my app, here is my code in app.js :
import React from 'react'
import {
BrowserRouter,
Link,
Switch,
Route,
Redirect,
withRouter
} from 'react-router-dom'
import { routes } from './router-config'
import Login from './modules/Login'
import fakeAuth from './Auth'
import About from './modules/About'
import Protected from './modules/Protected'
import './App.css';
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
fakeAuth.isAuthenticated ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}}/>
)
)}/>
)
const AuthButton = withRouter(({ history }) => (
fakeAuth.isAuthenticated ? (
<div>
Welcome! <button onClick={() => {
fakeAuth.signout(() => history.push('/login'))
}}>Sign out</button>
<ul>
<li><Link to="/about">About</Link></li>
<li><Link to="/protected">Protected Page</Link></li>
</ul>
</div>
) : (
<Redirect to={{
pathname: '/login'
}}/>
)
))
const App = () => (
<BrowserRouter>
<div>
<AuthButton/>
<Route path="/login" component={Login}/>
<PrivateRoute path="/about" component={About}/>
<PrivateRoute path="/protected" component={Protected}/>
</div>
</BrowserRouter>
)
export default App
Login.js
import React, { Component } from 'react'
import {
Redirect
} from 'react-router-dom'
import fakeAuth from '../Auth'
class Login extends React.Component {
state = {
redirectToReferrer: false
}
login = () => {
fakeAuth.authenticate(() => {
this.setState({ redirectToReferrer: true })
})
}
render() {
const { from } = this.props.location.state || { from: { pathname: '/' } }
const { redirectToReferrer } = this.state
if (redirectToReferrer) {
return (
<Redirect to={from}/>
)
}
return (
<div>
<p>Please Login</p>
<div>
</div>
<Button onClick={this.login} type="primary">Log in</Button>
</div>
)
}
}
export default Login;
I really don't know if this is the best one for this.
+3
source to share