Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirect to login page using react-router v4

I'm new in React.

I want to create an amdin app that redirects to login by default (the main menu is hidden). Using react-router v4, based on this sample the menu is already shown by default. What is the best practice to do this? 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 able to click login and redirect to App, but when i refresh the page when in App, the url is changed to /login but the display is still in the App. Please help. Thanks a lot

like image 238
bubleh Avatar asked Jun 21 '17 02:06

bubleh


1 Answers

I solved this problem by creating component and load it in 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 don't really know if it's the best way to do this.

like image 186
bubleh Avatar answered Oct 07 '22 05:10

bubleh