React Router 中的 useOutlet 是 v6
版本新增的 Hook,用于在父路由組件中訪問當前嵌套的子路由元素。它提供了比 <Outlet>
組件更靈活的控制方式,適合需要根據子路由狀態進行動態處理的場景。
一、useOutlet的基本用法
import { useOutlet } from 'react-router-dom';function ParentLayout() {// 返回當前匹配的子路由元素(未匹配時返回 null)const outlet = useOutlet();return (<div><h1>Parent Layout</h1><nav>{/* 導航鏈接 */}</nav>{/* 等價于直接使用 <Outlet /> */}{outlet || <div>Default content when no sub-route matches</div>}</div>);
}
二、useOutlet的典型使用場景
2.1. 條件渲染布局
function AuthLayout() {const outlet = useOutlet();return (<div className="auth-layout">{outlet ? (// 有子路由時顯示帶背景的布局<div className="auth-background">{outlet}</div>) : (// 無子路由時顯示默認內容<Navigate to="/login" />)}</div>);
}
2.2. 動態處理子路由
function AnimationLayout() {const outlet = useOutlet();const [prevOutlet, setPrevOutlet] = useState(outlet);// 保留舊路由用于退場動畫if (outlet) setPrevOutlet(outlet);return (<AnimatePresence mode="wait"><motion.divkey={location.pathname}initial={{ opacity: 0 }}animate={{ opacity: 1 }}exit={{ opacity: 0 }}>{outlet || prevOutlet}</motion.div></AnimatePresence>);
}
三、useOutlet的路由配置示例
const router = createBrowserRouter([{path: '/',element: <ParentLayout />,children: [{path: 'dashboard',element: <Dashboard />,},{path: 'profile',element: <UserProfile />,}]}
]);
四、useOutlet的使用注意事項
4.1、上下文依賴
只能在被 <RouterProvider>
或 <BrowserRouter>
包裹的組件中使用,否則會拋出錯誤。
4.2、路由匹配規則
子路由需要正確配置在父路由的 children 數組中,且路徑需要正確嵌套:
// ? 錯誤配置(缺少父路徑)
children: [{ path: '/dashboard', ... }]// ? 正確配置
children: [{ path: 'dashboard', ... }] // 實際路徑為 /dashboard
4.3、null 值處理
當沒有匹配的子路由時返回 null,建議總是處理空狀態:
// 推薦寫法
{outlet || <FallbackComponent />}// 危險寫法(可能渲染 undefined)
{outlet}
4.4、性能優化
與 <Outlet>
不同,直接使用 useOutlet
不會自動處理 Suspense
,需要自行添加錯誤邊界:
function SafeOutlet() {const outlet = useOutlet();return <ErrorBoundary>{outlet}</ErrorBoundary>;
}
4.5、路由狀態更新
當 URL 變化但父路由保持匹配時,useOutlet
會返回新的 React 元素,可以用 useLocation
監聽變化:
const outlet = useOutlet();
const location = useLocation();useEffect(() => {console.log('Sub-route changed:', location.pathname);
}, [location]);
五、useOutlet 與 的對比
六、useOutlet 使用總結建議:
大多數簡單場景直接使用 <Outlet>
更合適
需要以下高級功能時選擇 useOutlet:
6.1、動態布局切換
6.2、路由過渡動畫
6.3、自定義空狀態處理
6.4、基于子路由的復雜條件渲染