score:0

Accepted answer

I think you are complicating the route protection a bit. react-router-dom@6 route rendering works quite differently in v6, we don't directly render a Route in our components, they are to be rendered into the Routes component or directly nested under other Route components for route nesting.

I suggest the following implementation:

//v6
import React from "react";
import { Navigate, Outlet } from "react-router-dom";

interface IConditionalRoute = {
  condition: boolean;
};

const ConditionalRoute = ({ condition = false }: IConditionalRoute) => {
  return condition ? <Outlet /> : <Navigate to={REDIRECT_DESTINATION} />;
};

export { ConditionalRoute };

Note: I'm not super strong in Typescript, so I might not have got the syntax completely correct, but I expect the interface/code should get you close to what you would need.

Usage:

The AdminRoute would be rendered on what is called a layout route, a route that renders an Outlet and wraps other Route components. Omit the path prop so the path of the nested routes is what is used for matching/rendering.

const AdminRoute: ConditionalRouteProps = () => {
  const { isAdmin } = useContext(UserContext);
  return <ConditionalRoute condition={isAdmin} />;
};

const TestRoutes: React.FC = () => {
  return (
    <Routes>
      <Route element={<AdminRoute />}>
        <Route path="/admin" element={<h1>Admin Page</h1>} />
      </Route>
      <Route path="/" element={<TestPage />} />
    </Routes>
  );
};

Related Query

More Query from same tag