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

如何扩展react-router-dom的Route组件以支持自定义props?

为react-router-dom的Route组件添加自定义name属性的解决方案

问题背景

我想给react-router-dom的Route组件添加自定义name属性,用来在页面顶部展示页面描述,同时希望这些自定义属性能被显式声明,方便在用户认证、页面布局的中间件中访问。但自己写的代码无法运行,报错:

Uncaught Error: [T] is not a component. All component children of must be a or <React.Fragment>

我之前的代码如下:

自定义Route组件代码

import { RouteProps, Route as R } from "react-router-dom"

type Props = RouteProps & {
    name?: string
}

export const T: React.FC<Props> = ({...props}) => {
    return <R {...props} />
}

路由配置代码

import { BrowserRouter, Routes } from "react-router-dom";
import { T } from "@components/Route"

const RoutesApp = () => {
  return (
    <BrowserRouter>
      <Routes>
        <T path="/" element={<Middleware />} >
          <T path="test" name="This is a page" element={<>test</>} />
        </T>
      </Routes>
    </BrowserRouter>
  );
};

export default RoutesApp;

中间件组件代码

import { Outlet } from "react-router-dom";

export const Middleware = () => {
  if(...)
    return <>
        <main>
          <h1>{name}</h1>
          <Outlet />
        </main>
    </>
  }
}

错误原因

react-router-dom v6对<Routes>的子组件有严格要求:必须是官方提供的<Route>组件或<React.Fragment>,自定义的包装组件(比如你写的T)不会被识别,因此抛出错误。同时v6的嵌套路由写法也和v5不同,不能直接用组件嵌套的方式定义子路由。

解决步骤

1. 扩展RouteProps类型(TS可选,JS可跳过)

先扩展官方的RouteProps类型,添加我们需要的name属性,确保类型检查通过:

import { RouteProps } from "react-router-dom";

export type CustomRouteProps = RouteProps & {
  name?: string;
};

2. 直接使用官方Route配置路由

不需要自定义包装组件,直接给官方<Route>添加name属性,同时按照v6的规则配置嵌套路由:

import { BrowserRouter, Routes, Route } from "react-router-dom";
import { Middleware } from "./Middleware";

const RoutesApp = () => {
  return (
    <BrowserRouter>
      <Routes>
        {/* 父路由:element渲染中间件,children定义子路由 */}
        <Route path="/" element={<Middleware />}>
          {/* 直接给官方Route添加自定义name属性 */}
          <Route 
            path="test" 
            name="This is a page" 
            element={<>test</>} 
          />
        </Route>
      </Routes>
    </BrowserRouter>
  );
};

export default RoutesApp;

3. 在中间件中获取自定义name属性

使用useMatches钩子获取当前匹配的路由信息,从中提取name属性:

import { Outlet, useMatches } from "react-router-dom";

export const Middleware = () => {
  // 获取所有匹配的路由数组,最后一项是当前页面的路由
  const matches = useMatches();
  const currentRoute = matches[matches.length - 1];
  const pageName = currentRoute?.name || "默认页面";

  // 这里可以添加你的用户认证逻辑
  return (
    <main>
      <h1>{pageName}</h1>
      <Outlet />
    </main>
  );
};

关键说明

  • v6的<Routes>只认官方<Route>,别再自定义包装组件当路由用
  • 嵌套路由通过父<Route>的children属性定义,父路由的element里用<Outlet>渲染子路由内容
  • useMatches能拿到所有匹配的路由元数据,包括我们自定义的name属性,适合在布局、中间件中统一处理页面信息

内容的提问来源于stack exchange,提问作者Luiz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:11:12