I am trying to set up some react router routes, using the newest v6 specifically. What I'd like to do is have a website with a rest-like hierarchy of pages, and be able to parse out the IDs easily. Specifically with two level of IDs on the path.
I'm having trouble with how I'm supposed to properly parse out the IDs from the url using react router paradigms. I could just use window.location.pathname
and parse it myself or with a lib like it was 2003, but theres got to be a more react way to do it.
Here is the basic desired structure of urls:
/collection/ (all collections)
/collection/123 (collection 123)
/collection/123/abc (collection 123, subgroup abc)
/collection/123/all (special handler, collection 123, all subgroups)
It seems I can use useParams()
, however when I console.log
that within my Screen it does not seem very helpful or structured at all. See below.
Should there be a better way to pull out the :id
or :groupId
specified in the routes? Instead of just one property for "*" that I still end up needing to parse myself anyway. I was hoping for a "id" and "groupId" property, but maybe I'm approaching it wrong.
// 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>
EDIT:
Based on solution below, this route structure does what I need. I didn't want to use the element
in the subroutes in my App.tsx as things are a little more complicated and I want to keep App.tsx light. Removing the element
property however works fine. I then just use useParams()
in the Screen to access all the params as I originally needed.
// 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 />}