skip to Main Content

I’m using react-router-dom 5.2.0

App.jsx

`<Route path="/shop">
<ProductListPage />
</Route>
<Route path="/shop/:page">
<ProductListPage />
</Route>
<Route path="/shop/:gender/:category?">
<ProductListPage />
</Route>
<Route path="/shop/:filter">
<ProductListPage />
</Route>`

ProductListPage.jsx

`import { useParams } from "react-router-dom";

export default function ProductListPage() {
let { page } = useParams();
let { gender, category } = useParams();
let { filter } = useParams();

console.log(page + " " + gender + " " + filter + " " + category);

return (
<div className="bg-light-gray-1">
  <ProductCategories />
  <ProductList />
  <ClientList />
</div>
);
}`

Can’t get page or gender or anything, just undefined.

I have one page for listing all products.
Second one is for pagination
Third one is for categorization
And fourth one is for filtering

But variables where i get from links is not working. For example;
"/shop/women/tshirt" "/shop/man/shoe" "/shop/1

I’ve tried to get values like this but keep getting undefined values.

`import { useParams } from "react-router-dom";

export default function ProductListPage() {
let { page } = useParams();
let { gender, category } = useParams();
let { filter } = useParams();

console.log(page + " " + gender + " " + filter + " " + category);

2

Answers


  1. In React-Router-DOM v5 the route order and path specificity matters. The routes are matched from the top-down in the order they are specified, and path="/shop" matches all path="/shop/*" routes as well, so it is the route that get rendered and renders the ProductsListPage component and no path parameters are set. This is why page, gender, and category are all undefined.

    Re-order the routes such that the more specific routes can be matched first before falling back to less specific routes.

    Note also that path="/shop/:page" and path="/shop/:filter" the same specificity, so only one or the other can be matched ever, whichever is listed first. This is effectively a duplicate route and one should be removed.

    Example:

    <Switch>
      ...
      <Route path="/shop/:gender/:category?">
        <ProductListPage />
      </Route>
      <Route path="/shop/:page">
        <ProductListPage />
      </Route>
      <Route path="/shop">
        <ProductListPage />
      </Route>
      ...
    </Switch>
    

    or

    <Switch>
      ...
      <Route path="/shop/:gender/:category?" component={ProductListPage} />
      <Route path="/shop/:page" component={ProductListPage} />
      <Route path="/shop" component={ProductListPage} />
      ...
    </Switch>
    

    React-Router-DOM 5 Route components can also take an array of paths, so instead of duplicating the routes that all render the same ProductListPage component you can declare a single route and pass the paths in an array. The path order still matters here as well.

    <Switch>
      ...
      <Route
        path={[
          "/shop/:gender/:category?",
          "/shop/:page",
          "/shop"
        ]}
      >
        <ProductListPage />
      </Route>
      ...
    </Switch>
    

    or

    <Switch>
      ...
      <Route
        path={[
          "/shop/:gender/:category?",
          "/shop/:page",
          "/shop"
        ]}
        component={ProductListPage}
      />
      ...
    </Switch>
    

    In ProductListPage you only need a single useParams hook call, all the params can be destructured from the returned params object.

    import { useParams } from "react-router-dom";
    
    export default function ProductListPage() {
      const { page, gender, category } = useParams();
    
      console.log({ page, gender, category });
    
      ...
    }
    
    Login or Signup to reply.
  2. Rearrange your App.jsx routes

    <Route path="/shop/:gender/:category?">
    <ProductListPage />
    </Route>
    <Route path="/shop/:page">
    <ProductListPage />
    </Route>
    <Route path="/shop/:filter">
    <ProductListPage />
    </Route>
    <Route path="/shop">
    <ProductListPage />
    </Route>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search