TypeScript实现私有路由时遇Property 'exact'不存在于RouteProps类型错误
问题:React Router v6 中私有路由实现的 TypeScript 类型错误
错误详情
类型{ exact: true; render: (routerProps: RouterProps) => Element; }无法赋值给类型IntrinsicAttributes & RouteProps。属性exact不存在于类型IntrinsicAttributes & RouteProps中。
原代码实现
import React, { Suspense } from "react"; import { Route, Routes, RouterProps, useLocation, Navigate } from "react-router-dom"; interface RenderRouteProps extends RouterProps {} const RenderRoute: React.FC<CustomRoute> = props => { const { component } = props; const Component: React.ComponentType<RenderRouteProps> = component! return ( <Route exact render={(routerProps: RouterProps) => <Component {...routerProps} {...props} />}/> ); }; const PrivateRoute = (props: PrivateRouteProps & {redirectPath?: RouteRedirectProps, animate?: boolean}) => { const location = useLocation(); const { appRoutes, redirectPath } = props; return ( <Suspense> <Routes location={location}> {appRoutes.map((route, index) => ( <RenderRoute key={index} {...route} /> ))} {redirectPath?.length && redirectPath.map((path, index) => ( path && <Navigate to={path.to} key={index} /> ))} </Routes> </Suspense> ) }; export default PrivateRoute;
解决方案
React Router v6 对<Route>的API做了重大调整,原代码里的exact和render都是v5的用法,需要适配v6的规则:
- 移除
exact属性:v6中路由默认精确匹配,无需手动设置exact;嵌套路由通过在组件内使用<Outlet>实现。 - 替换
render为element:v6的<Route>不再支持render回调,改用element直接传入JSX元素。 - 修正类型适配:调整
RenderRoute的类型定义,匹配v6的路由组件传参方式。
修改后的完整代码:
import React, { Suspense } from "react"; import { Route, Routes, useLocation, Navigate, RouteProps } from "react-router-dom"; // 定义路由项的类型 interface CustomRoute extends Omit<RouteProps, "element"> { component: React.ComponentType<any>; } interface PrivateRouteProps { appRoutes: CustomRoute[]; } interface RouteRedirectProps { to: string; } const RenderRoute: React.FC<CustomRoute> = props => { const { component: Component, ...rest } = props; // 用element替代render,直接传递组件实例 return <Route {...rest} element={<Component {...props} />} />; }; const PrivateRoute = (props: PrivateRouteProps & {redirectPath?: RouteRedirectProps[], animate?: boolean}) => { const location = useLocation(); const { appRoutes, redirectPath } = props; return ( <Suspense> <Routes location={location}> {appRoutes.map((route, index) => ( <RenderRoute key={index} {...route} /> ))} {redirectPath?.length && redirectPath.map((path, index) => ( <Navigate key={index} to={path.to} replace /> ))} </Routes> </Suspense> ) }; export default PrivateRoute;
补充说明:
- 若需要实现私有路由的权限校验逻辑,可在
RenderRoute内添加登录状态判断,比如:const RenderRoute: React.FC<CustomRoute> = props => { const { component: Component, ...rest } = props; const isAuthenticated = /* 这里替换为你的登录状态判断逻辑 */ true; return ( <Route {...rest} element={ isAuthenticated ? <Component {...props} /> : <Navigate to="/login" state={{ from: rest.path }} replace /> } /> ); };
内容的提问来源于stack exchange,提问作者indra khanal
相关产品推荐
相关产品推荐

