反应路由器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 路线,idgroupId 来自 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"}