我有基本的reactjs应用程序,我想实现某种经过身份验证的检查。因此,如果用户通过身份验证,他就可以访问页面,而不是用户必须重定向到/login。 这是根配置
export const privateRoutes: Array<RouteType> = [
{
path: '/users',
element: UsersPage,
exact: true,
}
];
export const publicRoutes: Array<RouteType> = [
{
path: '/login',
element: LoginPage,
exact: true,
},
];
我创建了检查身份验证的路由包装器:
interface PrivateRouteProps {
key: number,
path: string;
element: React.ReactNode;
}
const PrivateRoute: FC<PrivateRouteProps> = ({key, path, element}) => {
const {userIsAuthenticated, hasPermission} = usePermission();
return (
<Route
path={path}
element={userIsAuthenticated() ? element : <Navigate to="/login" />}
/>
);
};
这是路由服务:
export const RouterService: React.FC = () => {
return (
<Router>
<SecurityProvider>
<Routes>
{privateRoutes.map((route: RouteType, index: number) => (
<PrivateRoute
key={index}
path={route.path}
element={<Layout>
<route.element/>
</Layout>}
/>
))}
{publicRoutes.map((route: RouteType, index: number) => (
<PrivateRoute
key={index}
path={route.path}
element={<BaseLayout>
<route.element/>
</BaseLayout>}
/>
))}
</Routes>
</SecurityProvider>
</Router>
);
在浏览器控制台中我得到:
history.ts:494 Uncaught Error: [PrivateRoute] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
我做错了什么以及如何正确实现此功能?
React Router 在路由中需要的是一个
<Route />
元素。你的包装打破了这种模式。
所以你需要类似下面的东西:
export const RouterService: React.FC = () => {
return (
<Router>
<SecurityProvider>
<Routes>
{privateRoutes.map((route: RouteType, index: number) => (
<Route
key={index}
path={route.path}
element={YOUR_ELEMENT_HERE}
/>
))}
</Routes>
</SecurityProvider>
</Router>
);
YOUR_ELEMENT_HERE
可以替换为您创建的 PrivateRoute
HOC。
你可以这样做:
const PrivateRoute: FC<PrivateRouteProps> = ({key, path, children}) => {
const {userIsAuthenticated, hasPermission} = usePermission();
if(!userIsAuthenticated()) <Navigate to="/login" />;
return <>{children}</>;
};
然后用这个图案替换
YOUR_ELEMENT_HOC
<PrivateRoute>
<UsersPage />
</PrivateRoute>
为了使事物变得动态,您可以转换这些元素的数组。 还有一种使用
Outlets
来做到这一点的机制。这会让事情变得更容易。