React Router复用路由组件报错:非Route组件无法作为Routes子组件
React Router 子路由复用组件报错解决方案
问题场景
尝试复用包含多条重复路由的组件,创建DocumentsRoutes组件返回多个<Route>,将其嵌套在path为"packages/:packageId"的<Route>中作为子路由时,出现如下报错:
[DocumentsRoutes]不是
组件, 的所有子组件必须是 或<React.Fragment>
代码示例
export const DocumentsRoutes = () => { return ( <> <Route path={abc} element={<component1 />} /> <Route path={bcd} element={<component2 />} /> <Route path={def} element={<component3 />} /> <Route path={af} element={<component4 />} /> <Route path={ef} element={<component5 />} /> <Route path="ef" element={<component6 />} /> </> ); }; <Route path="packages/:packageId" element={<DocumentsPackageRoot />}> <DocumentsRoutes /> </Route>
错误信息
history.ts:480 Uncaught Error: [DocumentsRoutes] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment> at invariant (history.ts:480:11) at components.tsx:582:5 at react.development.js:1195:17 at react.development.js:1158:17 at mapIntoArray (react.development.js:1049:23) at mapChildren (react.development.js:1157:3) at Object.forEachChildren [as forEach] (react.development.js:1194:3) at createRoutesFromChildren (components.tsx:566:18) at components.tsx:577:9 at react.development.js:1195:17
解决方案
React Router v6 严格要求<Route>的直接子元素必须是<Route>或<React.Fragment>,自定义组件无法被识别为合法的子路由容器。可以通过以下两种方式解决:
方法一:将组件改为返回路由元素数组,直接调用展开
修改DocumentsRoutes使其返回<Route>元素的数组,在父路由中直接调用该函数展开内容,而非使用组件标签:
export const DocumentsRoutes = () => [ <Route path={abc} element={<component1 />} key="doc-route-1" />, <Route path={bcd} element={<component2 />} key="doc-route-2" />, <Route path={def} element={<component3 />} key="doc-route-3" />, <Route path={af} element={<component4 />} key="doc-route-4" />, <Route path={ef} element={<component5 />} key="doc-route-5" />, <Route path="ef" element={<component6 />} key="doc-route-6" /> ]; // 父组件中使用 <Route path="packages/:packageId" element={<DocumentsPackageRoot />}> {DocumentsRoutes()} </Route>
注意给每个<Route>添加唯一key属性,避免React警告。
方法二:使用路由配置数组 + useRoutes钩子
定义可复用的路由配置对象数组,通过useRoutes钩子统一渲染路由结构,这种方式更符合React Router v6的推荐写法:
// 定义可复用的路由配置 export const documentsRoutesConfig = [ { path: abc, element: <component1 /> }, { path: bcd, element: <component2 /> }, { path: def, element: <component3 /> }, { path: af, element: <component4 /> }, { path: ef, element: <component5 /> }, { path: "ef", element: <component6 /> } ]; // 在父组件中使用useRoutes import { useRoutes } from 'react-router-dom'; const AppRoutes = () => { return useRoutes([ { path: "packages/:packageId", element: <DocumentsPackageRoot />, children: documentsRoutesConfig // 复用子路由配置 } ]); };
内容的提问来源于stack exchange,提问作者Raphael
相关产品推荐
相关产品推荐

