首页 > 解决方案 > 使用“组件”道具而不是“渲染”道具创建 PrivateRoute

问题描述

const PrivateRoute = ({ component, ...rest }) => {
  return (
    <Route
      {...rest}

      // OPTION 1
      component={!loggedInUser ? <Redirect to="/login" /> : component}

      // OPTION 2
      render={()=>(!loggedInUser ? <Redirect to="/login" /> : component())}

    />
  );
};

您更喜欢以上哪一项,为什么?我发现我无法将新的 useParam() 钩子与 OPTION 2 一起使用,因为它告诉我我正在使用功能组件主体之外的钩子。

标签: reactjsreact-router

解决方案


这是一个很好的路由门,它支持组件、渲染、权限和在缺少权限的情况下重定向

import React from 'react';
import PropTypes from 'prop-types';
import { Redirect, Route } from 'react-router-dom';

/* eslint-disable no-nested-ternary */
const RouteGate = props => {
  const {
    component: Component,
    hasPermission,
    redirectTo,
    render,
    ...rest
  } = props;

  return (
    <Route
      render={() =>
        hasPermission ? (
          Component ? (
            <Component {...props} />
          ) : (
            render()
          )
        ) : (
          <Redirect
            to={{
              pathname: redirectTo,
            }}
          />
        )
      }
      {...rest}
    />
  );
};

RouteGate.propTypes = {
  component: PropTypes.func,
  render: PropTypes.func,
  hasPermission: PropTypes.bool,
  redirectTo: PropTypes.string,
};

RouteGate.defaultProps = {
  hasPermission: true,
  redirectTo: '',
};

export default RouteGate;

将它与组件一起使用的示例:

<RouteGate
    path={paths.profile} // route of the profile, eg: /profile
    component={Profile} // component of the profile page
    hasPermission={isLoggedIn} // a flag in user selectors
    redirectTo={paths.login} // route of the login page eg: /login
/>

一个带有渲染的例子:

<RouteGate
    path={paths.profile}
    render={() => <Profile />}
    hasPermission={isLoggedIn}
    redirectTo={paths.login}
/>

推荐阅读