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







All Articles