skip to Main Content

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?

3

Answers


  1. You are using a hard coded string, the slug will not be replaced.
    you can use backticks.

    to={routers.category+`${item.slug}`}
    
    Login or Signup to reply.
  2. In my opinion, if you change your routes object structure your problem is solved. You can separate pathnames from routes.

    For example:

    const HOME_PATH = '/'
    const CATEGORY_PATH = '/category'
    

    Then your routes object something like the below:

    const routes = {
        home: HOME_PATH,
        category: `${CATEGORY_PATH}/:slug`,
    }
    

    Then you can solve your problem:

    array.map((item) => {
        return (
            <NavLink
                key={item.id}
                to={CATEGORY_PATH + '/' + item.slug}>
                {item.slug}
            </NavLink>
        )
    })
    
    Login or Signup to reply.
  3. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search