PrivateRoute 在 reactjs react-router-dom 中不起作用

Posted

技术标签:

【中文标题】PrivateRoute 在 reactjs react-router-dom 中不起作用【英文标题】:PrivateRoute not working in reactjs react-router-dom 【发布时间】:2019-07-02 19:15:30 【问题描述】:

在我的 react.js 项目中集成 PrivateRoute HOC 时,我完全陷入困境。

这是我的路线文件

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);

我对此彻底崩溃了,但并没有摆脱这个问题。为什么PrivateRoute 中的控制台不显示值

react 和 react-router-dom 版本有什么问题

提前谢谢你!!!

【问题讨论】:

您的意思是当您转到仪表板或管理组件时,控制台日志不打印任何内容? 您是否尝试访问仪表板或管理页面来激活此console.log @dnp1204 是的,你是对的 @Weedoze 是的,但它没有任何安慰 控制台有没有报错 【参考方案1】:

您拥有的PrivateRoute 组件是正确的,但是您只需重新订购您的Routes 即可使其正常工作。 /AdminManagement 路由应该在 / 之前,因为 Switch 会渲染第一个匹配的路由,Route 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

【讨论】:

谢谢...但它可以部分工作。它总是将我重定向到/login。为什么会这样? @Profer 因为必须在登录时设置 localStorage 否则它将永远无法工作 @Profer,您能否通过上述答案解决上述问题。 @Profer,不用担心获奖。我上次发表评论后没有收到您的任何回复,这就是我想确认的原因 在我上次发表评论后没有收到您的任何回复对此表示歉意【参考方案2】:

这是我处理私人路线的方式,也许它也会对您有所帮助。我有 protectedRoutes 作为包含路由的数组。你可以随心所欲地安装它们。

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:在原代码基础上添加完整示例

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);

【讨论】:

这不能回答 OP 的问题 这只是处理手头问题的不同方法。我同意它没有回答这个问题,但它可能有助于达到预期的结果。如果不是,我很乐意删除答案【参考方案3】:

尝试将库更改为react-cookie

let PrivateRoute = ( component: Component, cookies, ...rest ) => (
  <Route
    ...rest
    render=props =>
      cookies.get("name") ? (
        <Component ...props />
      ) : (
        <Redirect
          to=
            pathname: "/login",
            state:  from: props.location 
          
        />
      )
    
  />
);

https://codesandbox.io/s/015k0jl0ql

【讨论】:

这不能回答 OP 的问题 + OP 已经在使用 react-cookie 库 为什么不呢?如果您更改 lib,您可以从 cookie 中看到 console.log 中的数据 OP 需要使用当前库的解决方案。不需要另一个库来解决他的问题。

以上是关于PrivateRoute 在 reactjs react-router-dom 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

用于身份验证的 PrivateRoute 组件

将自定义数据传递给 React 中的 PrivateRoute 组件

使用 PrivateRoute 响应异步登录检查

React Router - PrivateRoute,登录后重定向到原始目的地

在 Typescript 项目中实现 react-router PrivateRoute

react privateRoute