Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PrivateRoute not working in reactjs react-router-dom

I am completely stuck when integrating PrivateRoute HOC in my react.js project.

Here is my route file

import React, { Component } from "react";
import { Route, Redirect, Switch, BrowserRouter as Router } from 'react-router-dom';
import Dashboard from "../view/Dashboard/Dashboard";
import Login from "../view/Login/Login";
import Admin from "../view/UserManagement/Admin";
import cookie from 'react-cookies'

const PrivateRoute = ({ component, ...rest }) => {
  const isAuthed = cookie.load('token')
  console.log(isAuthed, 'dddddddddddddddddddd')
  return (
    <Route {...rest} exact
      render = {(props) => (
        isAuthed ? (
          <div>
            {React.createElement(component, props)}
          </div>
        ) :
        (
          <Redirect
            to={{
              pathname: '/login',
              state: { from: props.location }
            }}
          />
        )
      )}
    />
  )
}

class MainPanel extends Component {

  render() {
    return (
      <div style={{ direction: direction }}> 
        <Router>
          <Switch>
            <Route path="/login" component={Login}/>
            <PrivateRoute path="/" component={Dashboard} />
            <PrivateRoute path="/AdminManagement" component={Admin} />
           </Switch>
        </Router>
      </div>
    )
  }
}
export default withNamespaces('common') (MainPanel);

I am totally break my head with this but didn't get rid out of that issue. Why my console inside the PrivateRoute doesn't show the values

Is there any issue with the react and react-router-dom versions

Thank you in advance!!!

like image 882
Profer Avatar asked Feb 08 '19 14:02

Profer


People also ask

What is Privateroute react?

The private route component is used to protect selected pages in a React app from unauthenticated users.

Is react Router dom deprecated?

react-dom : ReactDOM.render has been deprecated. Using it will warn and run your app in React 17 mode. react-dom : ReactDOM.hydrate has been deprecated. Using it will warn and run your app in React 17 mode.


2 Answers

The PrivateRoute component that you have is correct, You however only need to re-order your Routes for them to work correctly. /AdminManagement route should come before / since Switch renders the first matching Route and a Route path will also match its prefix path

class MainPanel extends Component {

  render() {
    return (
      <div style={{ direction: direction }}> 
        <Router>
          <Switch>
            <Route path="/login" component={Login}/>
            <PrivateRoute path="/AdminManagement" component={Admin} />
            <PrivateRoute path="/" component={Dashboard} />
           </Switch>
        </Router>
      </div>
    )
  }
}
export default withNamespaces('common') (MainPanel);

Working demo

like image 77
Shubham Khatri Avatar answered Sep 18 '22 04:09

Shubham Khatri


Here is how I handle my private routes, maybe it will help you also. I have protectedRoutes as an array with the routes. you can fit them as you like.

const routes = [
  {
    path: '/login', exact: true, name: 'Login', component: Login,
  },
];

const protectedRoutes = [
  {
    path: '/admin', exact: true, name: 'Admin', component: Admin,
  },
];

<Switch>

    {routes.map((route, idx) => (route.component ? (
         <Route
             key={idx}
             path={route.path}
             exact={route.exact}
             name={route.name}
             render={props => (
             <route.component {...props} />
             )}
          />
            )
     : (null)))}

     {protectedRoutes.map((route, idx) => (route.component ? (
          <Route
              key={idx}
              path={route.path}
              exact={route.exact}
              name={route.name}
              render={props => (
                isAuth
                  ? <route.component {...props} />
                  : <Redirect to="/login" />
                )}
           />
       )
       : (null)))}
        
</Switch>

LE: added full example based on the original code

import React, { Component } from 'react';
import { Route, Redirect, Switch, BrowserRouter as Router } from 'react-router-dom';
import Dashboard from '../view/Dashboard/Dashboard';
import Login from '../view/Login/Login';
import Admin from '../view/UserManagement/Admin';
import cookie from 'react-cookies';

const routes = [
  {
    path: '/login', exact: true, name: 'Login', component: Login,
  },
];

const protectedRoutes = [
  {
    path: '/', exact: true, name: 'Dashboard', component: Dashboard,
  },
  {
    path: '/AdminManagement', exact: true, name: 'Admin', component: Admin,
  },
];

class MainPanel extends Component {

  constructor(props) {
    super(props);
    this.state = {
      isAuthed: cookie.load('token'),
    },
  };

  render() {
    const { isAuthed } = this.state;
    return (
      <div style={{ direction: direction }}>
        <Router>
          <Switch>
            {routes.map((route, idx) => (route.component ? (
                <Route
                  key={idx}
                  path={route.path}
                  exact={route.exact}
                  name={route.name}
                  render={props => (
                    <route.component {...props} />
                  )}
                />
              )
              : (null)))}

            {protectedRoutes.map((route, idx) => (route.component ? (
                <Route
                  key={idx}
                  path={route.path}
                  exact={route.exact}
                  name={route.name}
                  render={props => (
                    isAuth
                      ? <route.component {...props} />
                      : <Redirect to="/login" />
                  )}
                />
              )
              : (null)))}
          </Switch>
        </Router>
      </div>
    )
  }
}

export default withNamespaces('common')(MainPanel);
like image 30
Sabbin Avatar answered Sep 22 '22 04:09

Sabbin