assembler
assembler

Reputation: 3300

Reactjs react router dom useParams not working with dynamic url

Using "react-router-dom": "^5.2.0" and "react": "16.8.6",

I have this:

<Switch>
   <Route path="/users" component={Users} />
   <Route path="/users/:id" component={Users} />
</Switch>

and in the Users component:

const param = useParams();
console.log(param);

So if I enter /users or /users/10 always param renders as empty object. What am I missing here?

Upvotes: 10

Views: 27714

Answers (3)

Wilson Ibekason
Wilson Ibekason

Reputation: 51

import your useparams from react-router-dom instead of react-router Like this :

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

const {yourId} = useParams();
console.log(yourId);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Upvotes: 0

Konrad Grzyb
Konrad Grzyb

Reputation: 1985

I am not using Switch. In my case, by mistake I imported useParams from 'react-router' and not from 'react-router-dom'. After import

import { useParams } from 'react-router-dom';

I got good params.

Upvotes: 4

Brian Thompson
Brian Thompson

Reputation: 14365

The Switch component will only render its first match.

The first Route that matches the path /users/10 is <Route path="/users" component={Users} />.

This means that even though you have a second Route that says the "10" should be a param called id, its ignoring it and treating it as the first Route does which has no params.

You can easily correct this behavior by using the exact prop on the first Route:

<Route exact path="/users" component={Users} />

This will instruct react-router to only match that route if the URL matches the path exactly, and will allow /users/10 to pass down to the Route you actually want it to match. Then you will have the params available that you expect.

Upvotes: 10

Related Questions