Arne Oldenhave
Arne Oldenhave

Reputation: 221

Get multiple URL parameters using useParams() hook

I am trying to pass multiple parameters in a url using React-Router 5.1 and the useParams hook in a Functional component.

However I encounter really strange behavior.

I paste the url into the client.

Url:

 http://localhost:3000/onboarding/eventId=5e9a173f9166f800128c04d1&groupId=5e9a173f9166f800128c04dc&userId=5e9a173f9166f800128c04da 

Path:

<Route path = '/onboarding/:eventId?/:groupId?/:userId?' exact component = {OnboardingViewController} />

Strange thing #1: I have to make the params optional, or the browser just hangs forever.

I fish them out using all these strategies:

    var   {  eventId, groupId, userId } = useParams();
    var   {  eventId } = useParams();
    var   {  groupId } = useParams();
    var   {  userId  } = useParams();

Strange thing #2: Unfortunately when trying to use these params this happens:

{userId: undefined, eventId: "eventId=5e9a173f9166f800128c04d1&groupId=5e9a173f9166f800128c04dc&userId=5e9a173f9166f800128c04da", groupId: undefined}

The hook just takes the first param and interprets the rest a part of te first.

Strange thing #3: Since adding this url params query accessing the page laoding is extremely slow, multiple seconds.

What am I not seeing, doing wrong?

ANSWER:

What I was doing wrong: I was using url/eventId=123. This is wrong. You just need to supply the resource at the right place in the URL url/1/2/3.

correct:

http://localhost:3000/onboarding/5e9aaf4fc27583001190834e/5e9aaf60c275830011908361/5e9aaf4fc275830011908357

You then tell the Router that those things will be called eventId & groupId & userId.

 <Route path = '/onboarding/:eventId/:groupId/:userId' exact component = {OnboardingViewController} />

Then you can access these in the component using the userPrams() hook.

var  { eventId,  groupId, userId } = useParams();

Thanks everyone!

Upvotes: 12

Views: 38772

Answers (3)

Golden Feather
Golden Feather

Reputation: 61

If you have to read the multiple parameters on the same page, Here is the folder structure I have created. So the folder structured goes like

app -> products -> [...category] -> page.tsx

Here is the URL that will pass where shoes is the category and 1 is product id http://localhost:3000/products/shoes/1

In the page.tsx under [...category] folder, I will check if URL parameters object has more than 1 keys,

  1. If yes, that means category and product id was passed in the url parameters
  2. If no, then only category was passed in the url Hence the code goes as

enter image description here

Here I am destructuring a category ( which is url parameter) by a Variable Index ( 0th index for category and 1st index for product id

({[0]:category , [1]:product_id} = category)

Upvotes: 0

Drew Reese
Drew Reese

Reputation: 202520

You are mixing up match parameters with URL query parameters.

The URL query parameters can be retrieved from the location object using the useLocation hook.

Given URL http://localhost:3000/onboarding/?eventId=5e9a173f9166f800128c04d1&groupId=5e9a173f9166f800128c04dc&userId=5e9a173f9166f800128c04da

{
  pathname: '/onboarding/',
  search: '?eventId=5e9a173f9166f800128c04d1&groupId=5e9a173f9166f800128c04dc&userId=5e9a173f9166f800128c04da'
}

would need a route path="/onboarding/" though

You can use a QueryParameter processing library to then convert these to a map object.

If you could massage your URL to be in the form: http://localhost:3000/onboarding/5e9a173f9166f800128c04d1/5e9a173f9166f800128c04dc/5e9a173f9166f800128c04da

Then the route path='/onboarding/:eventId/:groupId/:userId' can then match the path params returned by useParams.

const { eventId, groupId, userId } = useParams();

Upvotes: 5

Adrian
Adrian

Reputation: 945

Your Route structure and Route doesn't match

If you want to use params in your URL would be http://localhost:3000/onboarding/5e9a173f9166f800128c04d1/5e9a173f9166f800128c04dc/5e9a173f9166f800128c04da

And your Route component would be:

<Route path = '/onboarding/:eventId/:groupId/:userId' exact component = {OnboardingViewController} />

And then you can use this in the OnboardingViewControllercomponent:

 var   {  eventId, groupId, userId } = useParams();
 console.log(eventId,groupId,userId)

Upvotes: 13

Related Questions