'How to create HOC component with protected route?
I'm using react-router dom v6 and I have ProtectedRoute like
export const ProtectedRoute = ({
children,
}: {
children: JSX.Element;
}) => {
let location = useLocation();
const auth = useAuth();
if (!auth.isAuthenticated) {
return <Navigate to="/login" state={{ from: location }} />;
}
// if (isAuthenticated && !userHasRequiredRole) {
// return <AccessDenied />;
// }
return children;
};
In my AppRouter
const AppRouter = () => {
let elements = useRoutes([
// These are the same as the props you provide to <Route>
{ path: '/login', element: <LoginPage /> },
{
path: '/',
element: (
// [1] 👈
<ProtectedRoute>
<BasicLayout />
</ProtectedRoute>
),
children: [
{
path: 'sale',
element: (
// [2] 👈
<ProtectedRoute>
<Sale />
</ProtectedRoute>
),
}
]
}
])
return elements
}
- Can I create HOC component so I dont need to write like this over time (.ie WithProtectedRoute) ?
- Do I need to put the component inside ProtectedRoute every time like this since I put in on path: '/'?
Solution 1:[1]
While you could create a withProtectedRoute HOC and wrap each component export you want to protect, there's a more "react-router-dommethod. Instead of rendering achildrenprop you could render anOutletcomponent for nestedRoutecomponent and render theProtectedRoute` now as a layout component.
Example:
import { Navigate, Outlet } from 'react-router-dom';
export const ProtectedRoute = () => {
const location = useLocation();
const auth = useAuth();
return auth.isAuthenticated
? <Outlet />
: <Navigate to="/login" state={{ from: location }} replace />;
};
...
const elements = useRoutes([
// These are the same as the props you provide to <Route>
{ path: '/login', element: <LoginPage /> },
{
element: <ProtectedRoute />,
children: [
{
path: '/',
element: <BasicLayout />,
children: [
{
path: 'sale',
element: <Sale />,
}
],
},
],
},
]);
Read more about layout routes here.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Drew Reese |
