I'm using react-router-dom v6.8.1 (the latest version as of now) and previously used a third party library called use-react-router-breadcrumbs to set up breadcrumbs, but according to its documentation, they It is now recommended to use the "built-in react-router method", the documentation is here. It's based on attaching a breadcrumb to each route's handle object and using the useMatches hook to retrieve it.
So I rewrote the code, but it has a pretty big flaw that I can't fix. Suppose I have 3 routes, 2 and 3 are nested under 1:
{ path: '/', element: <Layout />, handle: { crumb: () => 'Home', }, children: [ { path: '/users', element: <UserList />, handle: { crumb: () => 'Users', }, }, { path: '/users/:id', element: <UserDetails />, handle: { crumb: () => <DynamicUserNameCrumb />, }, }, ] }
Using a custom library, you can go to /users/:id and get the breadcrumbs for each route, making the entire breadcrumb navigation look like this:
“Home -> Users -> John Doe”
However, when using the new built-in method and useMatches() hook, I can only match routes 1 and 3. Route 2 (/users) is not considered a match and I cannot access the breadcrumbs for that route. The result is this, which is not what I want:
“Home -> John Doe”
So my question is: How should you handle this situation? My first thought was to nest route 3 below 2 so that the breadcrumbs would be displayed correctly, but in reality it would render as the component defined by route 2 (user list) while I only wanted to render route 1 (layout) and 3 (user details page).
I expected useMatches() to accept configuration to return partial matches, but it seems this hook doesn't accept any input.
I'm about to fall back and go back to a 3rd party library, but wanted to ask here before doing so since they clearly recommend using the native solution based on useMatches and handle objects. I guess if this is the officially recommended way of handling react-router breadcrumbs, there must be a solution.
P粉1139388802024-01-11 11:17:49
From what I understand, this is because "/users"
and "/users/:id"
are brother routes. Reconstruct the routing configuration so that "/users/:id"
becomes a sub-route of "/users"
, so that there is a "logical path" from "/ Each segment from "
to "users"
to ":id"
.
Example:
const router = createBrowserRouter([ { path: "/", element: <Layout />, handle: { crumb: () => "Home" }, children: [ { path: "/users", handle: { crumb: () => "Users" }, children: [ { index: true, element: <UserList /> }, { path: "/users/:id", element: <UserDetails />, handle: { crumb: () => <DynamicUserNameCrumb /> } } ] } ] } ]);