I have the following array:
const tabsList = [
{
pathPattern: 'users/'
label: 'Manage users'
},
{
pathPattern: 'users/:id',
label: 'Edit user profile'
}
]
I need a method from react-router-dom
to tell me which of the above array entries matches the current pathname.
Based on that, I will be able to color the active list item in my component styles.
I found the method useMatch()
which looks like does almost what I want, however, it does not accept an array, it only accepts one string pattern to use for comparison.
// example: current path is /users/82374023854321
const isAllUsersMatch = useMatch('/users') // null
const isUserIdMatch = useMatch('/users/:id') // { ...PathMatch<string> }
it works, but it's not good, I have to create a separate variable like that for every item in the array.
Is there something like the following in react-router-dom
?
const tabsList = [
{
pathPattern: 'users/'
label: 'Manage users'
},
{
pathPattern: 'users/:id',
label: 'Edit user profile'
}
]
const activeListItem = tabsList.some((listItem)=> doesItMatch(listItem.pathPattern))
I would have done this with the hook, but in react you can't use a hook inside a callback, so the following would not work:
// const activeListItem = tabsList.some((listItem)=> doesItMatch(listItem.pathPattern))
const activeListItem = tabsList.some((listItem)=> useMatch(listItem.pathPattern)) // ERROR
You are on the right track iterating over the tabsList
array. If all you need is to match the current path to one in a configuration object/array, then instead of using the useMatch
hook, which doesn't work in a nested callback function, you can use the matchPath
utility function that the useMatch
hook uses directly.
import { matchPath, useLocation } from "react-router-dom";
const tabsList = [
{
pathPattern: "users/",
label: "Manage users"
},
{
pathPattern: "users/:id",
label: "Edit user profile"
}
];
...
const { pathname } = useLocation();
const activeListItem = tabsList.find(({ pathPattern }) =>
matchPath(pathPattern, pathname)
);
And the above abstracted into a custom hook:
const useTabsListMatches = (tabsList = []) => {
const { pathname } = useLocation();
return tabsList.find(({ pathPattern }) =>
matchPath(pathPattern, pathname)
);
}
const activeListItem = useTabsListMatches(tabsList);