I have a config route :
const routers = {
home: '/',
category: '/category/:slug',
}
and an array :
array = [
{ id: 1, slug: 'table'},
{ id: 2, slug: 'chair'},
]
I use array.map()
to generate a list of NavLink
components:
array.map(item => {
return <NavLink key={item.id} to={routers.category+item.slug}>
{item.slug}
</NavLink>
})
But it doesn't work. The result is localhost:3000/category/:slugtable
and localhost:3000/category/:slugchair
.
The expected result is localhost:3000/category/table
.
How can I solve it?
The issue is that for the link target you are using string concatenation.
to={routers.category+item.slug}
This results in link targets like "/category/:slug" + "chair"
which results in string literals "/category/:slugchair"
which likely isn't what you expected or have a route path to match.
react-router
exports a path generating utility, oddly enough, named generatePath
.
generatePath
interpolates a set of params into a route path string with:id
and*
placeholders. This can be useful when you want to eliminate placeholders from a route path so it matches statically instead of using a dynamic parameter.generatePath("/users/:id", { id: "42" }); // "/users/42" generatePath("/files/:type/*", { type: "img", "*": "cat.jpg", }); // "/files/img/cat.jpg"
Use generatePath
to take the "/category/:slug"
path and the slug
param to generate the target path.
import { NavLink, generatePath } from 'react-router-dom';
...
array.map(item => (
<NavLink key={item.id} to={generatePath(routers.category, item)}>
{item.slug}
</NavLink>
))
The slug
property on item
will be assigned to the ":slug"
route path param.