React Router Dom v6中如何创建携带GET参数的路由
React Router Dom v6 路由匹配查询参数正确实现方案
React Router v6 的路由路径(path)只会匹配URL的路径名部分,不会识别?后面的查询字符串(query string),把查询参数写在path里的写法是完全无效的,正确实现方式如下:
第一步:修正路由path配置
不需要也不能把查询参数写在path字段里,只需要配置路径部分即可:
/shorts/:userShortId?:不管后面带不带ab_channel查询参数、带什么查询参数,只要路径前缀是/shorts就会匹配,userShortId参数设为可选/watch:不管后面带v、ab_channel还是其他查询参数,只要路径是/watch就会匹配
修正后的完整路由配置代码:
export default function App() { return ( <BrowserRouter basename='/'> <GlobalStyle /> <Routes> <Route path='/' element={<HomePage />} /> <Route path='/login' element={<HomePage />} /> <Route path='/shorts/:userShortId?' element={<HomePage />} /> <Route path='/watch' element={<HomePage />} /> <Route path='/feed'> <Route path='subscriptions' element={<HomePage />} /> <Route path='library' element={<HomePage />} /> </Route> <Route path='/channel/:userChannelId' element={<HomePage />}> <Route path='videos' element={<HomePage />} /> <Route path='playlists' element={<HomePage />} /> <Route path='community' element={<HomePage />} /> <Route path='channels' element={<HomePage />} /> <Route path='about' element={<HomePage />} /> </Route> <Route path='*' element={<NotFoundPage />} /> </Routes> </BrowserRouter> ); }
第二步:在组件内读取参数
路由匹配成功后,用v6内置的钩子读取路径参数和查询参数即可:
- 用
useParams读取路径上的动态参数,比如userShortId、userChannelId - 用
useSearchParams读取?后面的查询参数,比如v、ab_channel
示例代码:
import { useSearchParams, useParams } from 'react-router-dom'; export default function HomePage() { // 读取路径参数 const pathParams = useParams(); // 读取查询参数 const [searchParams] = useSearchParams(); // 取对应参数值 const videoId = searchParams.get('v'); // 对应/watch?v=xxx里的xxx const abChannel = searchParams.get('ab_channel'); // 对应ab_channel=xxx里的xxx const userShortId = pathParams.userShortId; // 对应/shorts/:userShortId的路径值 // 如需参数校验直接在这里处理即可,比如/watch路由没有v参数就跳404 // if (window.location.pathname === '/watch' && !videoId) return <NotFoundPage /> return ( // 页面业务逻辑 ) }
补充说明
- 如果需要强制要求某些查询参数必传,可以写简单的路由守卫逻辑包裹对应路由的element,在守卫内判断参数是否存在,不符合要求直接重定向或展示404即可,不要在path字段里写
?、&这类查询参数匹配规则,v6本身不支持这种写法,甚至会导致路由匹配异常。 - 这种设计的优势是查询参数的顺序不影响路由匹配,比如
/watch?v=123&ab_channel=test和/watch?ab_channel=test&v=123会被同一个路由匹配,不需要写重复的路由规则。
内容的提问来源于stack exchange,提问作者THIAGO DE BONIS
相关产品推荐
相关产品推荐

