如何在React中正确处理非PrivateRoutes?

时间:2018-07-24 06:20:27

标签: javascript reactjs react-router

我的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;

1 个答案:

答案 0 :(得分:1)

有几种处理专用路由的方法,一种方法是编写您编写的自定义登录路由,以防止用户访问/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>
  );
};