You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 07:35:26