反应路由器6路由参数
react router 6 route params
我正在尝试设置一些 React 路由器路由,具体使用最新的 v6。我想要做的是拥有一个具有类似于休息的页面层次结构的网站,并且能够轻松解析出 ID。特别是在路径上有两级 ID。
我在使用 React 路由器范例正确解析 url 中的 ID 时遇到了问题。我可以只使用 window.location.pathname
并自己解析它,或者像 2003 年那样使用 lib,但是必须有一种反应更灵敏的方法来完成它。
这里是 urls 的基本结构:
/collection/ (all collections)
/collection/123 (collection 123)
/collection/123/abc (collection 123, subgroup abc)
/collection/123/all (special handler, collection 123, all subgroups)
我似乎可以使用 useParams()
,但是当我 console.log
在我的屏幕中时,它似乎没有太大帮助或根本没有结构化。见下文。
是否应该有更好的方法来拉出路由中指定的:id
或:groupId
?而不是只有一个属性对于“*”,我仍然最终需要解析自己。我希望有一个“id”和“groupId”属性,但也许我做错了。
// App.tsx
<BrowserRouter>
<Routes>
<Route path="/collection/*" element={<CollectionScreen />} />
</Routes>
</BrowserRouter>
// CollectionScreen.tsx
const params = useParams()
console.log(params);
// {*: ''} // path: /collection
// {*: '123'} // path: /collection/123
// {*: '123/abc'} // path: /collection/123/abc
...
<Routes>
<Route path=":id/*" element={<Collection />} />
<Route path=":id/all" element={<CollectionAll />} />
<Route path=":id/:groupId" element={<CollectionGroup />} />
</Routes>
编辑:
基于下面的解决方案,这个路由结构可以满足我的需要。我不想在 App.tsx 的子路径中使用 element
,因为事情有点复杂,我想保持 App.tsx 轻便。删除 element
属性 但是效果很好。然后我只需在屏幕中使用 useParams()
来访问我最初需要的所有参数。
// App.tsx
<Route path="/collection/*" element={<CollectionsScreen />}>
<Route path=":id/*" />
<Route path=":id/all" />
<Route path=":id/:groupId" />
</Route>
// CollectionScreen.tsx
const params = useParams<{ id?: string; groupId?: string }>();
const { id, groupId } = params;
...
// simplified here, but easy access to id/groupId here is helpful
{!id && <Collection />}
{id && groupId && groupId === "all" && <CollectionAll />}
{id && groupId && groupId !== "all" && <CollectionGroup />}
useParams
仅挂钩 returns 当前 Routes
组件范围内的路由参数。
例如,如果路径是 "/collection/123/456"
那么:
CollectionScreen
看到{*: "123/456"}
其中 *
来自 parent CollectionScreen
路线。
CollectionGroup
看到{*: "123/456", id: "123", groupId: "456"}
其中 *
来自 parent CollectionScreen
路线,id
和 groupId
来自 child CollectionGroup
组件。
CollectionScreen
无法进一步查看路由参数,因为它正在渲染一个 Routes
组件,该组件有效地“控制”了其下方的参数。路由的一个小重构可以让 CollectionScreen
看到它下面的路由参数路由。
应用程序
<BrowserRouter>
<Routes>
<Route path="/collection/*">
<Route path=":id" element={<CollectionScreen />}>
<Route index element={<Collection />} />
<Route path="all" element={<CollectionAll />} />
<Route path=":groupId" element={<CollectionGroup />} />
</Route>
</Route>
</Routes>
</BrowserRouter>
收藏画面
const params = useParams();
console.log("CollectionScreen", params);
return (
<>
...
<Outlet />
</>
);
现在所有路由组件都看到相同的 params
object。
CollectionScreen {*: "123/456", id: "123", groupId: "456"}
CollectionGroup {*: "123/456", id: "123", groupId: "456"}
我正在尝试设置一些 React 路由器路由,具体使用最新的 v6。我想要做的是拥有一个具有类似于休息的页面层次结构的网站,并且能够轻松解析出 ID。特别是在路径上有两级 ID。
我在使用 React 路由器范例正确解析 url 中的 ID 时遇到了问题。我可以只使用 window.location.pathname
并自己解析它,或者像 2003 年那样使用 lib,但是必须有一种反应更灵敏的方法来完成它。
这里是 urls 的基本结构:
/collection/ (all collections)
/collection/123 (collection 123)
/collection/123/abc (collection 123, subgroup abc)
/collection/123/all (special handler, collection 123, all subgroups)
我似乎可以使用 useParams()
,但是当我 console.log
在我的屏幕中时,它似乎没有太大帮助或根本没有结构化。见下文。
是否应该有更好的方法来拉出路由中指定的:id
或:groupId
?而不是只有一个属性对于“*”,我仍然最终需要解析自己。我希望有一个“id”和“groupId”属性,但也许我做错了。
// App.tsx
<BrowserRouter>
<Routes>
<Route path="/collection/*" element={<CollectionScreen />} />
</Routes>
</BrowserRouter>
// CollectionScreen.tsx
const params = useParams()
console.log(params);
// {*: ''} // path: /collection
// {*: '123'} // path: /collection/123
// {*: '123/abc'} // path: /collection/123/abc
...
<Routes>
<Route path=":id/*" element={<Collection />} />
<Route path=":id/all" element={<CollectionAll />} />
<Route path=":id/:groupId" element={<CollectionGroup />} />
</Routes>
编辑:
基于下面的解决方案,这个路由结构可以满足我的需要。我不想在 App.tsx 的子路径中使用 element
,因为事情有点复杂,我想保持 App.tsx 轻便。删除 element
属性 但是效果很好。然后我只需在屏幕中使用 useParams()
来访问我最初需要的所有参数。
// App.tsx
<Route path="/collection/*" element={<CollectionsScreen />}>
<Route path=":id/*" />
<Route path=":id/all" />
<Route path=":id/:groupId" />
</Route>
// CollectionScreen.tsx
const params = useParams<{ id?: string; groupId?: string }>();
const { id, groupId } = params;
...
// simplified here, but easy access to id/groupId here is helpful
{!id && <Collection />}
{id && groupId && groupId === "all" && <CollectionAll />}
{id && groupId && groupId !== "all" && <CollectionGroup />}
useParams
仅挂钩 returns 当前 Routes
组件范围内的路由参数。
例如,如果路径是 "/collection/123/456"
那么:
CollectionScreen
看到{*: "123/456"}
其中
*
来自 parentCollectionScreen
路线。CollectionGroup
看到{*: "123/456", id: "123", groupId: "456"}
其中
*
来自 parentCollectionScreen
路线,id
和groupId
来自 childCollectionGroup
组件。
CollectionScreen
无法进一步查看路由参数,因为它正在渲染一个 Routes
组件,该组件有效地“控制”了其下方的参数。路由的一个小重构可以让 CollectionScreen
看到它下面的路由参数路由。
应用程序
<BrowserRouter>
<Routes>
<Route path="/collection/*">
<Route path=":id" element={<CollectionScreen />}>
<Route index element={<Collection />} />
<Route path="all" element={<CollectionAll />} />
<Route path=":groupId" element={<CollectionGroup />} />
</Route>
</Route>
</Routes>
</BrowserRouter>
收藏画面
const params = useParams();
console.log("CollectionScreen", params);
return (
<>
...
<Outlet />
</>
);
现在所有路由组件都看到相同的 params
object。
CollectionScreen {*: "123/456", id: "123", groupId: "456"} CollectionGroup {*: "123/456", id: "123", groupId: "456"}