如何在 React Router 4 中实现经过身份验证的路由?所有答案都已过时

我试图实现经过身份验证的路由,但发现 React Router 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>

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

它出现在(v4)文档中,它暗示了类似的东西react-router

<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


答案 1

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

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

现在你的 s 可以看起来像这样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 Router v4保护路由和身份验证


答案 2

所有答案都已过时

在2021年,根据react-router-dom文档,该组件的prop将用于遗留用途,在我的情况下,它甚至不起作用(我使用的是react-router-dom 5.2.0)。renderRoute

这适用于

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

const RouteRequiresLogin: FC<React.ComponentProps<typeof Route>> = props => {
   const userIsLogged = useLoginStatus();

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

export default RouteRequiresLogin;

用法:

/* A route that requires login */
<RouteRequiresLogin path="/dashboard">
   <DashboardPage />
</RouteRequiresLogin>

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