已用<Routes>包裹仍触发Route需嵌套Routes错误的原因及用法咨询
React Router DOM v6 路由迁移问题排查与解决
问题背景
正在将旧代码迁移至react-router-dom v6,原v5实现代码如下:
v5 代码实现
const AddRoute = ({ usergroups, ...props }) => ( usergroups.length > 0 ? <Route {...props} /> : <Route component={NotFound} /> )
<Switch> <AddRoute usergroups={userGroups.files} exact path="/some/path/add" render={(props) => ( <Name {...props} services={services} view={true} /> )} /> </Switch>;
尝试转换为v6版本后,两种写法均触发相同错误:
router.js:269 Uncaught Error: A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>
尝试的v6写法1
const AddRoute = ({ usergroups, ...props }) => ( usergroups.length > 0 ? <Route {...props} /> : <Route element={<NotFound />} /> );
<Routes> <Route path="/some/path/add" element={ <AddRoute usergroups={userGroups.metricprofiles} element={<Name services={services} view={true} />} />} /> </Routes>
尝试的v6写法2
<Routes> <Route path="/some/path/add" element={<AddRoute usergroups={userGroups.files} />} > <Route element={<Name services={services} view={true} />} /> </Route> </Routes>
错误原因
React Router DOM v6 对<Route>的使用规则做了严格限制:<Route>必须是<Routes>的直接子元素,不能在自定义组件内部渲染<Route>。你编写的AddRoute组件内部直接返回<Route>,当它作为<Route>的element属性值渲染时,相当于在普通组件层级中嵌套了<Route>,违反了v6的路由规则,因此触发报错。
解决方案
改造AddRoute组件,让它不再返回<Route>,而是根据权限判断直接返回对应的页面组件或NotFound组件,将其作为路由的element属性值使用。
正确的v6实现代码
首先修改AddRoute组件:
const AddRoute = ({ usergroups, children }) => { // 根据用户组权限决定渲染内容 return usergroups.length > 0 ? children : <NotFound />; };
然后在路由中使用:
<Routes> <Route path="/some/path/add" element={ <AddRoute usergroups={userGroups.files}> <Name services={services} view={true} /> </AddRoute> } /> </Routes>
如果需要直接传入组件而非使用children,也可以这样写:
const AddRoute = ({ usergroups, element }) => { return usergroups.length > 0 ? element : <NotFound />; }; // 路由使用示例 <Routes> <Route path="/some/path/add" element={ <AddRoute usergroups={userGroups.files} element={<Name services={services} view={true} />} /> } /> </Routes>
这种写法完全符合v6的路由规则,AddRoute作为普通组件渲染在<Route>的element中,内部不再嵌套<Route>,而是直接返回页面组件,避免了报错。
内容的提问来源于stack exchange,提问作者dean89
相关产品推荐
相关产品推荐

