React Router v6如何实现基于数据的Route递归渲染?
问题根因
React Router v6 对路由节点做了强校验:
<Routes>下的直接子元素只能是原生<Route>组件或<React.Fragment>- 嵌套
<Route>的子路由节点也必须符合上述要求
你封装的RecursiveRoute属于自定义函数组件,哪怕内部返回值是<Route>,在React元素树中它的类型标识是RecursiveRoute而非官方要求的Route,因此会直接抛出你看到的错误:
[RecursiveRoute] is not a
component. All component children of must be a or <React.Fragment>
可行实现方案
方案1:递归函数直接渲染Route(适配原有逻辑,改造成本最低)
去掉自定义组件包裹层,改用纯递归函数直接返回Route元素树,完全符合React Router的校验规则,支持任意深度嵌套:
import React from "react"; import { BrowserRouter, Routes, Route} from "react-router-dom"; import "./styles.css"; function GenericPage() { return <div className="page">Generic page</div>; } const nav = { slug: "", title: "Home", children: [ { slug: "foo", title: "Foo" }, { slug: "bar", title: "Bar" } ] }; // 递归渲染路由节点,直接返回原生Route元素 const renderRecursiveRoutes = (node) => { return ( <Route path={node.slug} element={<GenericPage />}> {node.children?.map((child) => renderRecursiveRoutes(child))} </Route> ); }; export default function App() { return ( <BrowserRouter> <Routes> {renderRecursiveRoutes(nav)} </Routes> </BrowserRouter> ); }
方案2:使用官方useRoutes钩子(推荐长期维护场景)
React Router v6 原生提供useRoutes配置式路由API,天然支持对象结构的路由配置,不需要手动渲染Route组件,扩展性更强:
import React from "react"; import { BrowserRouter, useRoutes } from "react-router-dom"; import "./styles.css"; function GenericPage() { return <div className="page">Generic page</div>; } const nav = { slug: "", title: "Home", children: [ { slug: "foo", title: "Foo" }, { slug: "bar", title: "Bar" } ] }; // 将业务导航数据转换为useRoutes要求的配置格式 const formatRouteConfig = (node) => { return { path: node.slug, element: <GenericPage />, children: node.children?.map(child => formatRouteConfig(child)) } }; function AppRoutes() { const routeConfig = [formatRouteConfig(nav)]; return useRoutes(routeConfig); } export default function App() { return ( <BrowserRouter> <AppRoutes /> </BrowserRouter> ); }
两种方案都可以实现任意深度的递归路由渲染,如果你只是想快速修复原有代码,选方案1即可;如果后续要扩展路由懒加载、权限拦截、索引路由等能力,优先选方案2。
内容的提问来源于stack exchange,提问作者jugglingcats
相关产品推荐
相关产品推荐

