前言
matchRoutes
是 React Router v6
提供的一個核心工具函數,主要用于匹配路由配置與當前路徑。它在服務端渲染(SSR)、數據預加載、權限校驗等場景中非常實用。下面詳細解析其用法、注意事項和案例分析:
1、基本用法
import { matchRoutes } from 'react-router-dom';const routes = [{ path: '/', element: <Home /> },{ path: '/users', element: <Users /> },{ path: '/users/:id', element: <UserDetail /> },
];const location = { pathname: '/users/123' };
const matches = matchRoutes(routes, location);
返回值 matches
結構示例:
[{route: { path: '/users', element: <Users /> }, // 匹配的父路由pathname: '/users', // 匹配的完整路徑pathnameBase: '/users', // 匹配的基礎路徑(不含子路由)params: {} // 父路由參數},{route: { path: '/users/:id', element: <UserDetail /> },pathname: '/users/123',pathnameBase: '/users/123',params: { id: '123' } // 解析的動態參數}
]
2、關鍵注意事項
2.1、返回數組結構
matchRoutes()
返回一個數組,包含所有匹配的嵌套路由對象(從根路由到葉子路由)。即使只有一個路由匹配,也會返回長度為1的數組。
2.2、路由配置必須完整
需傳入完整的路由數組(包含所有嵌套的 children),否則深層路由無法匹配:
// ? 錯誤:缺少嵌套配置
const routes = [{ path: '/users', element: <Users /> }];// ? 正確:包含子路由
const routes = [{path: '/users',element: <Users />,children: [{ path: ':id', element: <UserDetail /> }]
}];
2.3、動態參數解析
動態參數(如 :id)會被自動解析并存入 match.params 中。
2.4、通配符路由 * 匹配
通配符路由只在沒有其他路由匹配時生效:
const routes = [{ path: '/users', element: <Users /> },{ path: '/*', element: <NotFound /> }
];
matchRoutes(routes, { pathname: '/unknown' }); // 匹配 /* 路由
2.5、索引路由(Index Route)匹配
當路徑精確匹配父路由時,會匹配 index: true
的子路由:
const routes = [{path: '/dashboard',element: <DashboardLayout>,children: [{ index: true, element: <DashboardHome /> }, // 匹配 /dashboard{ path: 'settings', element: <Settings /> }]
}];
2.6、大小寫敏感問題
默認不區分大小寫。如需區分,在路由配置中設置 caseSensitive: true:
{ path: '/CaseSensitive', caseSensitive: true, element: <Component /> }
3、常見應用場景
3.1、 服務端渲染(SSR
)數據預取
// 服務端代碼
import { matchRoutes } from 'react-router-dom/server';function handleRequest(req, res) {const matches = matchRoutes(routes, req.url);const promises = matches.map(match => {// 假設路由組件有靜態方法 loadDatareturn match.route.element?.type?.loadData?.(match);});Promise.all(promises).then(() => {// 數據加載完成后渲染應用const html = renderToString(<App />);res.send(html);});
}
3.2、 客戶端權限校驗
// 路由守衛組件
const AuthGuard = ({ children }) => {const location = useLocation();const matches = matchRoutes(routes, location);const needAuth = matches?.some(match => match.route.requiresAuth);if (needAuth && !isLoggedIn) {return <Redirect to="/login" />;}return children;
};
3.3、 提取動態參數(非組件環境)
// 工具函數中獲取參數
function getUserIdFromPath(pathname) {const matches = matchRoutes([{ path: '/users/:id' }], pathname);return matches?.[0]?.params.id; // '123'
}
4、易錯點與解決方案
返回 null 的問題: 是路徑未匹配任何路由, 需要檢查路由配置或添加通配符路由 /*
子路由未匹配 的原因:是父路由配置未包含 children, 需要確保路由配置包含完整的嵌套結構
參數未解析 的原因: 是動態路由拼寫錯誤(如 :ID vs :id), 需要檢查路由的 path 定義一致性
索引路由不生效 的原因: 是父路由路徑后有額外字符(如 /dashboard/), 需要確保路徑精確匹配父路由
5、替代方案對比
useMatch Hook
:僅在組件內使用,返回當前路由的匹配信息。
useParams Hook
:組件內獲取動態參數。
手動正則匹配:不推薦,維護成本高且易出錯。
總結
matchRoutes
的核心價值在于在非組件環境中獲得路由匹配信息。關鍵要點:
- 傳入完整的路由配置(含
children
) - 返回值是數組,需遍歷處理多層匹配
- 善用
pathnameBase
和params
解析路徑信息 - 在 SSR、路由攔截、工具函數中優先使用它
- 正確使用此 API 能顯著提升路由控制的靈活性與代碼可維護性。