React Router v6中如何正确使用Outlet并解决路由匹配错误
React Router v6 路由适配解决方案
问题根源
- 根路径
/(即ROUTES.HOME)未配置对应路由规则,你将这部分代码注释,直接触发"No routes matched location "/""错误。 - 路由保护组件(
IsUserRedirect和ProtectedRoute)沿用React Router v5的Route+render写法,而v6已完全废弃该用法,改用element属性,且不支持在保护组件内部嵌套Route。 - 注释的HOME路由中错误使用
<ROUTES.HOME />,这是路径常量而非组件,应替换为<Home />。
代码修正
1. 重构路由保护组件(Routes.js)
改为v6兼容的组件形式,直接根据用户状态返回内容或重定向,无需嵌套Route:
import React from 'react'; import { Navigate, useLocation } from 'react-router-dom'; export function IsUserRedirect({ user, loggedInPath, children }) { if (user) { return <Navigate to={loggedInPath} replace />; } return children; } export function ProtectedRoute({ user, children }) { const location = useLocation(); if (!user) { return <Navigate to="/signin" state={{ from: location }} replace />; } return children; }
2. 修复App.js路由配置
取消HOME路由注释,修正组件引用,移除v5的exact属性(v6路由默认精确匹配):
import React from "react"; import { BrowserRouter as Router, Route, Routes} from "react-router-dom"; import { Home, Browse, Signin, Signup } from "./pages"; import * as ROUTES from './constants/routes'; import { IsUserRedirect, ProtectedRoute } from "./helpers/routes"; export default function App() { const user = null; return ( <Router> <Routes> <Route path={ROUTES.SIGN_IN} element={ <IsUserRedirect user={user} loggedInPath={ROUTES.BROWSE} > <Signin /> </IsUserRedirect> } /> <Route path={ROUTES.SIGN_UP} element={ <IsUserRedirect user={user} loggedInPath={ROUTES.BROWSE} > <Signup /> </IsUserRedirect> } /> <Route path={ROUTES.BROWSE} element={ <ProtectedRoute user={user}> <Browse /> </ProtectedRoute> } /> <Route path={ROUTES.HOME} element={ <ProtectedRoute user={user}> <Home /> </ProtectedRoute> } /> </Routes> </Router> ); }
3. Outlet的正确使用场景
Outlet是v6用于嵌套路由的组件,仅当父路由需要渲染子路由内容时才会用到。你的场景是平级路由,无需使用Outlet。若后续需实现嵌套路由(如Browse下的子页面),示例如下:
// 父路由配置 <Route path="browse" element={<BrowseLayout />}> <Route index element={<BrowseHome />} /> <Route path="movies" element={<BrowseMovies />} /> </Route> // BrowseLayout组件 function BrowseLayout() { return ( <div> <h1>Browse导航栏</h1> {/* 子路由内容将渲染到此处 */} <Outlet /> </div> ); }
内容的提问来源于stack exchange,提问作者sakshi_
相关产品推荐
相关产品推荐

