web-dev-qa-db-ja.com

React Router V6を使用した保護されたルート

React-Routerの新しいバージョン6を使用してProtectecteRouteを書く正しい方法は何ですか?私はこれを書いたが、それはルートではありません

const PrivateRoute = ({ component: Component, ...props }) => {   
  if (!Component) return null;

  return props.isAuthenticated
    ? <Component />
    : <Navigate to={props.redirectLink} /> }

export default PrivateRoute;
 _
3
Victor

これがReact-Router V6ベータの最新の作業実装です。ただし、ユーザー出力を使用して保護されたルートを実装する方法はわかりません。彼らのドキュメンテーションは、両方の方法で保護された/プライベートルートを実装する方法についての例を追加するべきです。

ProtectedRouteコンポーネント

import React from 'react';
import PropTypes from 'prop-types';
import { Route } from 'react-router-dom';
import Forbidden from '../../views/errors/Forbidden';
import { useAuth } from '../../contexts/AuthContext';

const ProtectedRoute = ({ roles, element, children, ...rest }) => {
  const { user, login } = useAuth();

  if (!user) {
    login();
    return <></>;
  }

  if (roles.length > 0) {
    const routeRoles = roles.map((role) => role.toLowerCase());
    const userRoles = (user && user.roles ? user.roles : []).map((role) => role.toLowerCase());
    if (miscUtils.intersection(routeRoles, userRoles).length === 0) {
      return <Forbidden />;
    }
  }

  return (
    <Route element={element} {...rest}>
      {children}
    </Route>
  );
};

ProtectedRoute.propTypes = {
  roles: PropTypes.arrayOf(PropTypes.string),
  element: PropTypes.element,
  children: PropTypes.node,
};

ProtectedRoute.defaultProps = {
  roles: [],
  element: null,
  children: null,
};

export default ProtectedRoute;
 _

承認コンポーネント

import React from 'react';
import { Routes, Route, Navigate, Outlet } from 'react-router-dom';
import Login from './components/oauth/Login';
import Logout from './components/oauth/Logout';
import RenewToken from './components/oauth/RenewToken';
import ProtectedRoute from './components/ProtectedRoute';
import NotFound from './views/errors/NotFound';
import Index from './views/Index';
import MainContainer from './views/MainContainer';
import ViewUserProfile from './views/user/profile/ViewUserProfile';
import CreateUserProfile from './views/user/profile/CreateUserProfile';
import UpdateUserProfile from './views/user/profile/UpdateUserProfile';
import PartnerProfile from './views/partner/profile/PartnerProfile';

const AppRoutes = () => {
  return (
    <Routes>
      {/* auth pages (important: do not place under /auth path) */}
      <Route path="oauth/login" element={<Login />} />
      <Route path="oauth/logout" element={<Logout />} />
      <Route path="oauth/renew" element={<RenewToken />} />
      <Route element={<MainContainer />}>
        <Route path="/" element={<Index />} />

        {/* protected routes */}
        <ProtectedRoute path="user" element={<Outlet />}>
          <Route path="/" element={<Navigate to="profile" replace />} />

          <Route path="profile" element={<Outlet />}>
            <Route path="/" element={<ViewUserProfile />} />
            <Route path="create" element={<CreateUserProfile />} />
            <Route path="update" element={<UpdateUserProfile />} />
          </Route>
        </ProtectedRoute>

        <ProtectedRoute path="partner" roles={['partner']} element={<Outlet />}>
          <Route path="/" element={<Navigate to="profile" replace />} />
          <Route path="profile" element={<PartnerProfile />} />
        </ProtectedRoute>
      </Route>
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
};

export default AppRoutes;
 _
1
sebascomeau

これは実施例です。

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

const PrivateRoute = ({ component: Component, redirectTo, isAuth, path, ...props }) => {
    if(!isAuth) {
        return <Navigate to={redirectTo} />;
    }
    return <Route path={path} element={<Component />} />
};

export default PrivateRoute;
 _

使用法:

<Routes>
     <Route path="app" element={<DashboardLayout />}>
         <PrivateRoute isAuth={true} path="account" component={AccountView}  redirectTo='/login'/>
     </Route>
 </Routes>
 _