我在app.js中有这段代码,并配置了PrivateRoute,该路由要求用户登录,并且仅在设置了cookie的情况下才允许访问。但是,我想限制试图成功登录后尝试按/login的用户。我使用了PrivateRoute的逆逻辑并创建了LoginRoute,该目的可用于此目的,但想知道是否有更好的方法。

import React from 'react';
import {
  BrowserRouter as Router,
  Route,
  Switch,
  Redirect
} from 'react-router-dom';
import { ConnectedRouter } from 'connected-react-router'
import cookies from 'cookies-js';

import Home from './homeComponent';
import Login from './loginComponent';
import Dashboard from './dashboardComponent';
import NoMatch from './noMatchComponent';

const App = ({ history }) => {
  return (
    <ConnectedRouter history={history}>
        <Switch>
          <Route exact={true} path="/" component={Home} />
          <LoginRoute path="/login" component={Login} />
          <PrivateRoute path="/dashboard" component={Dashboard} />
          <Route component={NoMatch} />
        </Switch>
    </ConnectedRouter>
  );
};

const LoginRoute = ({ component: Component, rest }) => (
  <Route {...rest} render={(props) => (
    cookies.get('access-token')
      ? <Redirect to={{
          pathname: '/dashboard',
          state: { from: props.location }
        }} />
      : <Component {...props} />
  )} />
)

const PrivateRoute = ({ component: Component, rest }) => (
  <Route {...rest} render={(props) => (
    cookies.get('access-token')
      ? <Component {...props} />
      : <Redirect to={{
          pathname: '/login',
          state: { from: props.location }
        }} />
  )} />
)

export default App;

最佳答案

有几种处理私有路由的方法,一种方法是编写您编写的自定义登录路由,以防止用户访问已登录的/login。您需要在路线中进行的唯一更正是使用rest syntax correctly

const LoginRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={(props) => (
    cookies.get('access-token')
      ? <Redirect to={{
          pathname: '/dashboard',
          state: { from: props.location }
        }} />
      : <Component {...props} />
  )} />
)


和PrivateRoute

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={(props) => (
    cookies.get('access-token')
      ? <Component {...props} />
      : <Redirect to={{
          pathname: '/login',
          state: { from: props.location }
        }} />
  )} />
)


处理此问题的另一种方法是身份验证HOC。

const RequireAuth = (Component) => {

    return class App extends Component {

        render() {
           const { location } = this.props;
           if (cookies.get('access-token')) {
               if(location.pathname === '/login') {
                    return <Redirect to={'/dashboard'} />
               }
               return <Component {...this.props} />
           }
           return <Redirect to="/login"/>
        }
    }

}

export { RequireAuth }


你会用它像

const App = ({ history }) => {
  return (
    <ConnectedRouter history={history}>
        <Switch>
          <Route exact={true} path="/" component={Home} />
          <Route path="/login" component={RequireAuth(Login)} />
          <Route path="/dashboard" component={RequireAuth(Dashboard)} />
          <Route component={NoMatch} />
        </Switch>
    </ConnectedRouter>
  );
};

10-08 15:49