如何在 React 路由器4中实现经过身份验证的路由?

我试图实现认证路由,但发现反应路由器4现在阻止这个工作:

<Route exact path="/" component={Index} />
<Route path="/auth" component={UnauthenticatedWrapper}>
<Route path="/auth/login" component={LoginBotBot} />
</Route>
<Route path="/domains" component={AuthenticatedWrapper}>
<Route exact path="/domains" component={DomainsIndex} />
</Route>

错误是:

警告: 不应在同一路由中使用 <Route component><Route children>; 将忽略 <Route children>

在这种情况下,实现这一点的正确方法是什么?

它出现在 react-router(v4)文档中,表明类似于

<Router>
<div>
<AuthButton/>
<ul>
<li><Link to="/public">Public Page</Link></li>
<li><Link to="/protected">Protected Page</Link></li>
</ul>
<Route path="/public" component={Public}/>
<Route path="/login" component={Login}/>
<PrivateRoute path="/protected" component={Protected}/>
</div>
</Router>

但是,是否有可能实现这一点,同时将一系列路线组合在一起?


经过一些研究,我想出了这个:

import React, {PropTypes} from "react"
import {Route} from "react-router-dom"


export default class AuthenticatedRoute extends React.Component {
render() {
if (!this.props.isLoggedIn) {
this.props.redirectToLogin()
return null
}
return <Route {...this.props} />
}
}


AuthenticatedRoute.propTypes = {
isLoggedIn: PropTypes.bool.isRequired,
component: PropTypes.element,
redirectToLogin: PropTypes.func.isRequired
}

render()中执行操作是否正确?感觉不对。使用 componentDidMount或其他钩子似乎也不太正确。

210716 次浏览

您需要使用 Redirect组件。解决这个问题有几种不同的方法。这里有一个我喜欢的,有一个 PrivateRoute 组件,它接受一个 authed道具,然后基于该道具进行渲染。

function PrivateRoute ({component: Component, authed, ...rest}) {
return (
<Route
{...rest}
render={(props) => authed === true
? <Component {...props} />
: <Redirect to=\{\{pathname: '/login', state: {from: props.location}}} />}
/>
)
}

现在你的 Route可以看起来像这样

<Route path='/' exact component={Home} />
<Route path='/login' component={Login} />
<Route path='/register' component={Register} />
<PrivateRoute authed={this.state.authed} path='/dashboard' component={Dashboard} />

如果你仍然感到困惑,我写的这篇文章可能会有所帮助 使用 React 路由器 v4

保护路由和身份验证

看来你的犹豫是在创建自己的组件,然后在渲染方法中分派?您可以通过使用 <Route>组件的 render方法来避免这两种情况。除非您真的想要,否则不需要创建 <AuthenticatedRoute>组件。它可以像下面这样简单。注意 {...routeProps}扩展,确保继续将 <Route>组件的属性发送到子组件(本例中为 <MyComponent>)。

<Route path='/someprivatepath' render={routeProps => {


if (!this.props.isLoggedIn) {
this.props.redirectToLogin()
return null
}
return <MyComponent {...routeProps} anotherProp={somevalue} />


} />

看看 React 路由器 V4渲染文档

如果您确实希望创建一个专用组件,那么看起来您的方向是正确的。因为 React 路由器 V4是 纯声明式路由(它在描述中是这么说的) ,所以我不认为将重定向代码置于正常的组件生命周期之外是可行的。查看 反应路由器本身的代码,它们在 componentWillMountcomponentDidMount中执行重定向,具体取决于它是否是服务器端呈现。下面的代码非常简单,可以帮助您更好地处理将重定向逻辑放在何处的问题。

import React, { PropTypes } from 'react'


/**
* The public API for updating the location programatically
* with a component.
*/
class Redirect extends React.Component {
static propTypes = {
push: PropTypes.bool,
from: PropTypes.string,
to: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object
])
}


static defaultProps = {
push: false
}


static contextTypes = {
router: PropTypes.shape({
history: PropTypes.shape({
push: PropTypes.func.isRequired,
replace: PropTypes.func.isRequired
}).isRequired,
staticContext: PropTypes.object
}).isRequired
}


isStatic() {
return this.context.router && this.context.router.staticContext
}


componentWillMount() {
if (this.isStatic())
this.perform()
}


componentDidMount() {
if (!this.isStatic())
this.perform()
}


perform() {
const { history } = this.context.router
const { push, to } = this.props


if (push) {
history.push(to)
} else {
history.replace(to)
}
}


render() {
return null
}
}


export default Redirect

Tnx 泰勒麦金尼斯的解决方案。 我的想法来自 Tyler McGinnis 的想法。

const DecisionRoute = ({ trueComponent, falseComponent, decisionFunc, ...rest }) => {
return (
<Route
{...rest}


render={
decisionFunc()
? trueComponent
: falseComponent
}
/>
)
}

你可以像这样实现它

<DecisionRoute path="/signin" exact={true}
trueComponent={redirectStart}
falseComponent={SignInPage}
decisionFunc={isAuth}
/>

DecisionFunc 只是一个返回 true 或 false 的函数

const redirectStart = props => <Redirect to="/orders" />

安装反应路由器

然后创建两个组件,一个用于有效用户,另一个用于无效用户。

在 App.js 上试试这个

import React from 'react';


import {
BrowserRouter as Router,
Route,
Link,
Switch,
Redirect
} from 'react-router-dom';


import ValidUser from "./pages/validUser/validUser";
import InValidUser from "./pages/invalidUser/invalidUser";
const loggedin = false;


class App extends React.Component {
render() {
return (
<Router>
<div>
<Route exact path="/" render={() =>(
loggedin ? ( <Route  component={ValidUser} />)
: (<Route component={InValidUser} />)
)} />


</div>
</Router>
)
}
}
export default App;

我知道已经有一段时间了,但我一直在为私人和公共路线的 Npm 软件包工作。

以下是制作私人路线的方法:

<PrivateRoute exact path="/private" authed={true} redirectTo="/login" component={Title} text="This is a private route"/>

还可以创建只有未经授权的用户才能访问的 Public 路由

<PublicRoute exact path="/public" authed={false} redirectTo="/admin" component={Title} text="This route is for unauthed users"/>

希望能有所帮助!

我实现了使用-

<Route path='/dashboard' render={() => (
this.state.user.isLoggedIn ?
(<Dashboard authenticate={this.authenticate} user={this.state.user} />) :
(<Redirect to="/login" />)
)} />

验证道具将被传递给组件,例如注册,使用哪个用户状态可以被改变

import React from 'react';
import { Switch, Route } from 'react-router-dom';
import { Redirect } from 'react-router';


import Home from '../pages/home';
import Login from '../pages/login';
import Signup from '../pages/signup';
import Dashboard from '../pages/dashboard';


import { config } from '../utils/Config';


export default class AppRoutes extends React.Component {


constructor(props) {
super(props);


// initially assuming that user is logged out
let user = {
isLoggedIn: false
}


// if user is logged in, his details can be found from local storage
try {
let userJsonString = localStorage.getItem(config.localStorageKey);
if (userJsonString) {
user = JSON.parse(userJsonString);
}
} catch (exception) {
}


// updating the state
this.state = {
user: user
};


this.authenticate = this.authenticate.bind(this);
}


// this function is called on login/logout
authenticate(user) {
this.setState({
user: user
});


// updating user's details
localStorage.setItem(config.localStorageKey, JSON.stringify(user));
}


render() {
return (
<Switch>
<Route exact path='/' component={Home} />
<Route exact path='/login' render={() => <Login authenticate={this.authenticate} />} />
<Route exact path='/signup' render={() => <Signup authenticate={this.authenticate} />} />
<Route path='/dashboard' render={() => (
this.state.user.isLoggedIn ?
(<Dashboard authenticate={this.authenticate} user={this.state.user} />) :
(<Redirect to="/login" />)
)} />
</Switch>
);
}
}

点击这里查看完整的项目: https://github.com/varunon9/hello-react

(使用 Redux 进行状态管理)

如果用户尝试访问任何网址,首先我要检查是否访问令牌可用,如果没有重定向到登录页面, 一旦用户使用登录页面登录,我们将其存储在本地存储以及 redux 状态中。(本地存储或饼干。.我们暂时不谈这个话题)。
因为 reducx 状态作为更新和 private-ateroutes 将被重新呈现。现在我们有了权限令牌,所以我们要重定向到主页。

将解码的授权有效负载数据也存储在 redux 状态,并将其传递给响应上下文。(我们不必使用上下文,但访问任何嵌套的子组件的授权,这使得从上下文访问变得容易,而不是将每个子组件连接到 reducx)。.

所有不需要特殊角色的路由都可以在登录后直接访问。.如果需要类似管理员的角色(我们制作了一个受保护的路由,检查他是否有所需的角色,如果没有重定向到未授权的组件)

类似地,在任何组件中,如果必须禁用按钮或基于角色的某些东西。

你可以这样做

const authorization = useContext(AuthContext);
const [hasAdminRole] = checkAuth({authorization, roleType:"admin"});
const [hasLeadRole] = checkAuth({authorization, roleType:"lead"});
<Button disable={!hasAdminRole} />Admin can access</Button>
<Button disable={!hasLeadRole || !hasAdminRole} />admin or lead can access</Button>

那么,如果用户尝试在本地存储中插入虚拟令牌会怎样呢。因为我们有访问令牌,所以我们将重定向到 home 组件。由于 jwt 令牌是虚拟的,因此我的主组件将进行休息调用来获取数据,休息调用将返回未经授权的用户。所以我调用 logout (这将清除本地存储并再次重定向到登录页面)。 如果主页有静态数据而没有进行任何 api 调用(那么应该在后端进行令牌验证 api 调用,以便在加载主页之前检查令牌是否为 REAL)

Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Switch } from 'react-router-dom';
import history from './utils/history';




import Store from './statemanagement/store/configureStore';
import Privateroutes from './Privateroutes';
import Logout from './components/auth/Logout';


ReactDOM.render(
<Store>
<Router history={history}>
<Switch>
<Route path="/logout" exact component={Logout} />
<Route path="/" exact component={Privateroutes} />
<Route path="/:someParam" component={Privateroutes} />
</Switch>
</Router>
</Store>,
document.querySelector('#root')
);

V 史

import { createBrowserHistory as history } from 'history';


export default history({});

私人出口

import React, { Fragment, useContext } from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { AuthContext, checkAuth } from './checkAuth';
import App from './components/App';
import Home from './components/home';
import Admin from './components/admin';
import Login from './components/auth/Login';
import Unauthorized from './components/Unauthorized ';
import Notfound from './components/404';


const ProtectedRoute = ({ component: Component, roleType, ...rest })=> {
const authorization = useContext(AuthContext);
const [hasRequiredRole] = checkAuth({authorization, roleType});
return (
<Route
{...rest}
render={props => hasRequiredRole ?
<Component {...props} /> :
<Unauthorized {...props} />  }
/>)};


const Privateroutes = props => {
const { accessToken, authorization } = props.authData;
if (accessToken) {
return (
<Fragment>
<AuthContext.Provider value={authorization}>
<App>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" render={() => <Redirect to="/" />} />
<Route exact path="/home" component={Home} />
<ProtectedRoute
exact
path="/admin"
component={Admin}
roleType="admin"
/>
<Route path="/404" component={Notfound} />
<Route path="*" render={() => <Redirect to="/404" />} />
</Switch>
</App>
</AuthContext.Provider>
</Fragment>
);
} else {
return (
<Fragment>
<Route exact path="/login" component={Login} />
<Route exact path="*" render={() => <Redirect to="/login" />} />
</Fragment>
);
}
};


// my user reducer sample
// const accessToken = localStorage.getItem('token')
//   ? JSON.parse(localStorage.getItem('token')).accessToken
//   : false;


// const initialState = {
//   accessToken: accessToken ? accessToken : null,
//   authorization: accessToken
//     ? jwtDecode(JSON.parse(localStorage.getItem('token')).accessToken)
//         .authorization
//     : null
// };


// export default function(state = initialState, action) {
// switch (action.type) {
// case actionTypes.FETCH_LOGIN_SUCCESS:
//   let token = {
//                  accessToken: action.payload.token
//               };
//   localStorage.setItem('token', JSON.stringify(token))
//   return {
//     ...state,
//     accessToken: action.payload.token,
//     authorization: jwtDecode(action.payload.token).authorization
//   };
//    default:
//         return state;
//    }
//    }


const mapStateToProps = state => {
const { authData } = state.user;
return {
authData: authData
};
};


export default connect(mapStateToProps)(Privateroutes);

CheckAuth.js

import React from 'react';


export const AuthContext = React.createContext();


export const checkAuth = ({ authorization, roleType }) => {
let hasRequiredRole = false;


if (authorization.roles ) {
let roles = authorization.roles.map(item =>
item.toLowerCase()
);


hasRequiredRole = roles.includes(roleType);
}


return [hasRequiredRole];
};

解码后的 JWT 样本

{
"authorization": {
"roles": [
"admin",
"operator"
]
},
"exp": 1591733170,
"user_id": 1,
"orig_iat": 1591646770,
"email": "hemanthvrm@stackoverflow",
"username": "hemanthvrm"
}

基于 @ Tyler McGinnis的答案,我使用带有封装组件的 ES6语法嵌套路线做了一个不同的方法:

import React, { cloneElement, Children } from 'react'
import { Route, Redirect } from 'react-router-dom'


const PrivateRoute = ({ children, authed, ...rest }) =>
<Route
{...rest}
render={(props) => authed ?
<div>
{Children.map(children, child => cloneElement(child, { ...child.props }))}
</div>
:
<Redirect to=\{\{ pathname: '/', state: { from: props.location } }} />}
/>


export default PrivateRoute

使用它:

<BrowserRouter>
<div>
<PrivateRoute path='/home' authed={auth}>
<Navigation>
<Route component={Home} path="/home" />
</Navigation>
</PrivateRoute>


<Route exact path='/' component={PublicHomePage} />
</div>
</BrowserRouter>
const Root = ({ session }) => {
const isLoggedIn = session && session.getCurrentUser
return (
<Router>
{!isLoggedIn ? (
<Switch>
<Route path="/signin" component={<Signin />} />
<Redirect to="/signin" />
</Switch>
) : (
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
<Route path="/something-else" component={SomethingElse} />
<Redirect to="/" />
</Switch>
)}
</Router>
)
}

我以前的答案是不可扩展的。这里是我认为是好的方法-

你的路线 -

<Switch>
<Route
exact path="/"
component={matchStateToProps(InitialAppState, {
routeOpen: true // no auth is needed to access this route
})} />
<Route
exact path="/profile"
component={matchStateToProps(Profile, {
routeOpen: false // can set it false or just omit this key
})} />
<Route
exact path="/login"
component={matchStateToProps(Login, {
routeOpen: true
})} />
<Route
exact path="/forgot-password"
component={matchStateToProps(ForgotPassword, {
routeOpen: true
})} />
<Route
exact path="/dashboard"
component={matchStateToProps(DashBoard)} />
</Switch>

想法是在 component道具中使用一个包装器,如果不需要身份验证或者已经通过身份验证,它将返回原始组件,否则将返回默认组件,例如 Login。

const matchStateToProps = function(Component, defaultProps) {
return (props) => {
let authRequired = true;


if (defaultProps && defaultProps.routeOpen) {
authRequired = false;
}


if (authRequired) {
// check if loginState key exists in localStorage (Your auth logic goes here)
if (window.localStorage.getItem(STORAGE_KEYS.LOGIN_STATE)) {
return <Component { ...defaultProps } />; // authenticated, good to go
} else {
return <InitialAppState { ...defaultProps } />; // not authenticated
}
}
return <Component { ...defaultProps } />; // no auth is required
};
};

下面是一个简单的清洁保护路线

const ProtectedRoute
= ({ isAllowed, ...props }) =>
isAllowed
? <Route {...props}/>
: <Redirect to="/authentificate"/>;
const _App = ({ lastTab, isTokenVerified })=>
<Switch>
<Route exact path="/authentificate" component={Login}/>
<ProtectedRoute
isAllowed={isTokenVerified}
exact
path="/secrets"
component={Secrets}/>
<ProtectedRoute
isAllowed={isTokenVerified}
exact
path="/polices"
component={Polices}/>
<ProtectedRoute
isAllowed={isTokenVerified}
exact
path="/grants" component={Grants}/>
<Redirect from="/" to={lastTab}/>
</Switch>

isTokenVerified是一个检查授权令牌的方法调用,基本上它返回布尔值。

我也在寻找答案。这里所有的答案都很好,但是没有一个答案告诉我们如果用户在打开应用程序之后启动应用程序该如何使用它。(我的意思是一起使用 cookie)。

甚至不需要创建不同的 private-Route 组件

    import React, { Component }  from 'react';
import { Route, Switch, BrowserRouter, Redirect } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './stores';
import requireAuth from './components/authentication/authComponent'
import SearchComponent from './components/search/searchComponent'
import LoginComponent from './components/login/loginComponent'
import ExampleContainer from './containers/ExampleContainer'
class App extends Component {
state = {
auth: true
}




componentDidMount() {
if ( ! Cookies.get('auth')) {
this.setState({auth:false });
}
}
render() {
return (
<Provider store={store}>
<BrowserRouter>
<Switch>
<Route exact path="/searchComponent" component={requireAuth(SearchComponent)} />
<Route exact path="/login" component={LoginComponent} />
<Route exact path="/" component={requireAuth(ExampleContainer)} />
{!this.state.auth &&  <Redirect push to="/login"/> }
</Switch>
</BrowserRouter>
</Provider>);
}
}
}
export default App;

这是 authComponent

import React  from 'react';
import { withRouter } from 'react-router';
import * as Cookie from "js-cookie";
export default function requireAuth(Component) {
class AuthenticatedComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
auth: Cookie.get('auth')
}
}
componentDidMount() {
this.checkAuth();
}
checkAuth() {
const location = this.props.location;
const redirect = location.pathname + location.search;
if ( ! Cookie.get('auth')) {
this.props.history.push(`/login?redirect=${redirect}`);
}
}
render() {
return Cookie.get('auth')
? <Component { ...this.props } />
: null;
}
}
return  withRouter(AuthenticatedComponent)
}

下面我写了博客,你也可以在那里得到更深入的解释。

在 ReactJS 中创建受保护的路由

以下是我如何解决它与反应和打字稿。希望它有所帮助!

import * as React from 'react';
import { FC } from 'react';
import { Route, RouteComponentProps, RouteProps, Redirect } from 'react-router';


const PrivateRoute: FC<RouteProps> = ({ component: Component, ...rest }) => {
if (!Component) {
return null;
}
const isLoggedIn = true; // Add your provider here
return (
<Route
{...rest}
render={(props: RouteComponentProps<{}>) => isLoggedIn ? (<Component {...props} />) : (<Redirect to=\{\{ pathname: '/', state: { from: props.location } }} />)}
/>
);
};


export default PrivateRoute;
















<PrivateRoute component={SignIn} path="/signin" />

公认的答案是好的,但它 不能解决的问题 当我们需要我们的组件来反映 URL 中的变化时

例如,组件的代码类似于:

export const Customer = (props) => {


const history = useHistory();
...


}

然后你改变网址:

const handleGoToPrev = () => {
history.push(`/app/customer/${prevId}`);
}

组件不会重新加载!


一个更好的解决方案:

import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import store from '../store/store';


export const PrivateRoute = ({ component: Component, ...rest }) => {


let isLoggedIn = !!store.getState().data.user;


return (
<Route {...rest} render={props => isLoggedIn
? (
<Component key={props.match.params.id || 'empty'} {...props} />
) : (
<Redirect to=\{\{ pathname: '/login', state: { from: props.location } }} />
)
} />
)
}

用法:

<PrivateRoute exact path="/app/customer/:id" component={Customer} />

这只是初学者的一个基本方法,不适合专业的 redux 开发人员

import React, { useState, useEffect } from "react";
import {
Route,
BrowserRouter as Router,
Switch,
Redirect,
} from "react-router-dom";
import Home from "./components/Home";
import Dashboard from "./components/Dashboard";
import Login from "./components/Login";


function App() {
const [isAuth, setAuth] = useState(false);


const checkAuth = () => {
// Your auth logic here
setAuth(true);
};


useEffect(() => {
checkAuth();
});


return (
<Router>
<Switch>
<Route
path="/user/dashboard"
render={(props) =>
isAuth ? <Dashboard {...props} /> : <Redirect to="/" />
}
/>
<Route path="/login" component={Login} />
<Route path="/" component={Home} />
</Switch>
</Router>
);
}

所有答案都过时了

在2022年,Route组件的 render支柱用于遗留用途,根据反应路由器的文档甚至不再在 V5中工作,而在 V6中被删除。

相反,这种方法是有效的。 :

const RequireAuth: FC<{ children: React.ReactElement }> = ({ children }) => {
const userIsLogged = useLoginStatus(); // Your hook to get login status


if (!userIsLogged) {
return <LoginPage />;
}
return children;
};

用法:

/* A route that doesn't require login */
<Route
path="sign-up"
element={
<SignUpPage />
}
/>


/* A route that requires login */
<Route
path="dashboard"
element={
<RequireAuth>
<DashboardPage />
</RequireAuth>
}
/>

编辑: < strong > 我将代码示例更新到 React Router 的 v6

这是我自己的方法

const RedirectionUnit = () => {
const [user] = useContext(AuthContext);
const pathname = useLocation().pathname;
let redirectTo;
if (user === null) redirectTo = "login";
else if (pathname === "/")
if (user.type === "supervisor"      ) redirectTo = "all-parteners";
else if (user.type === "manager"    ) redirectTo = "all-employees";
else if (user.type === "employee"   ) redirectTo = "unfinished-tasks";
if (redirectTo && '/' + redirectTo !== pathname)
return <Redirect to={redirectTo} />;
return null;
};


const NavigationRoutes = () => {
return (
<>
<Route component={RedirectionUnit} />
{/* prettier-ignore */}
<Switch>
<Route exact path="/login"            component={Login} />
<Route exact path="/logout"           component={Logout} />
<Route exact path="/new-parteners"    component={NewParteners} />
<Route exact path="/all-parteners"    component={AllParteners} />
<Route exact path="/new-employees"    component={NewEmployees} />
<Route exact path="/all-employees"    component={AllEmployees} />
<Route exact path="/unfinished-tasks" component={UnfinishedTasks} />
<Route exact path="/finished-tasks"   component={FinishedTasks} />
<Route exact path="/finished-tasks"   component={FinishedTasks} />
<Route component={NotFound} />
</Switch>
</>
);
};

我喜欢@fermm 的答案,但是在他的实现中,如果用户没有登录,呈现的组件将不能与 URL 匹配。因此,它可能会让访客感到困惑。

所以

return (
<Route {...props}>{userIsLogged ? props.children : <LoginPage/>}</Route>
);

我建议使用:

return (
<Route {...props}>
{userIsLogged ? (
props.children
) : (
<Redirect
to=\{\{
pathname: "/login",
state: { from: location },
}}
/>
)}
</Route>
);

在这种情况下,您仍然会得到组件呈现,但是 URL 中的“/login”代替了前面的路由段。

我正在寻找一个解决方案,我的主路由器文件有一切需要认证的路由。不需要嵌套组件,也不复杂。下面是我的方法

import React from "react";
import { Routes, Route } from "react-router-dom";
import { Navigate } from "react-router-dom";
// Other imports




export default function AppRoutes() {
// This coming from react-redux
// After a user is logged in this will set in the global state
const { currentUser } = useCurrentUser();


const landing = <Landing />


const authenticate = (component) => {
return currentUser ? component : <Navigate to="/" />;
}


return (
<Routes>
<Route path="/" element={currentUser ? <Home /> : landing} />


<Route path="/blogs/:id" element={authenticate(<Blog />)} />
<Route path="/blogs/:id/edit" element={authenticate(<BlogEdit />)} />
<Route path="/profile" element={authenticate(<Profile />)} />
<Route path="*" element={<Navigate to="/" />} />
</Routes>
);
}

基于 TypeScript 的 解决方案@MaxThom,这里有一个可以将组件或呈现函数传递给 PrivateRoute 的选项:

import React from "react";
import { Route, Redirect, RouteProps, RouteComponentProps } from "react-router-dom";




const PrivateRoute: React.FC<RouteProps> = ({component, render, ...rest}) => {


const userIsLogged = window.localStorage.getItem('currentUsecase');
  

if (userIsLogged === undefined) return (
<Route render={
(props: RouteComponentProps<{}>) => <Redirect
to=\{\{ pathname: '/', state: { from: props.location } }}
/>
}/>
)
   

return (
<Route {...rest} render={render} component={component} />
)
};


export default PrivateRoute;

希望这个能帮上忙。