React-router Link, pass in params
Asked Answered
O

4

20

If you have a route such as:

<Route path="/users/:userId" />

And then you export that route, and so it can be used across your app, such as:

export const MY_ROUTE = '/users/:userId/';

<Route path={MY_ROUTE} />

How do you set the param in a link dynamically? i.e. I would like to do this:

<Link to={MY_ROUTE} params={{userId: 1}} />

but params is totally ignored... and query just makes a query (?userId=) not a param... any ideas?

Obeah answered 28/6, 2016 at 20:40 Comment(1)
What do you mean by set the param dynamically? The route should be matched automatically when you hit /users/123Tideway
E
14

Taken from React Router official docs:

From the upgrade guide from 1.x to 2.x:

<Link to>, onEnter, and isActive use location descriptors

<Link to> can now take a location descriptor in addition to strings. The query and state props are deprecated.

// v1.0.x

<Link to="/foo" query={{ the: 'query' }}/>

// v2.0.0

<Link to={{ pathname: '/foo', query: { the: 'query' } }}/>

Unfortunately, there's no support for passing in a param object, you yourself saw that.

In order to dynamically use the route you proposed, you would have to do something along the lines of:

<Link to={ MY_ROUTE.replace(':userId', '<someUserIdFromSomewhere>') }/>

Or you could further optimize by instead of exporting a string for MY_ROUTE, you could export a userLink function as such:

function userLink(userId) {
    return `/users/${userId}/`;
}

and then use that wherever you would want to use a Link to the route.

Below you can find supported parameters and API exposed on the Link component:

Router Link API

Epicycloid answered 28/6, 2016 at 20:45 Comment(1)
You can try using url-pattern to construct your urls: path={new UrlPattern(MY_ROUTE).stringify({ userId: 1})}. It is not a perfect match but for simple routes it can workAphasia
F
7

I know this is an old question, but with React Router V4 you can use the path-to-regexp package, which is also being used by React Router V4.

Example:

import {Link} from 'react-router-dom';
import {compile} from 'path-to-regexp';

const MY_ROUTE = '/users/:userId/';
const toPath = compile(MY_ROUTE);

// Now you can use toPath to generate Links dynamically
// The following will log '/users/42' to the console
console.log( toPath({ userId: 42 }) );

Of course you can use the toPath method to create proper links as well, example:

<Link to={toPath({ userId: 42 })}>My Link</Link>
Falcate answered 22/6, 2017 at 12:58 Comment(1)
or, even simpler: <Link to={`users/${user.id}`}>My Link</Link>Fairyfairyland
L
6

You could create a function which interpolate the userId param to create the route, something like this:

export const MY_ROUTE = (userId) => `/users/${userId}/`;

<Route path={MY_ROUTE(':userId')} />

And so in your component

<Link to={MY_ROUTE(1)} params={{userId: 1}} />

Try this solution here: https://jsbin.com/pexikoyiwa/edit?js,console

Limy answered 28/6, 2016 at 20:57 Comment(1)
This should be accepted answer, it allows to build both path required by router and actual path in the redirects in the clearest wayGulley
C
2

React Router v5 has a built in method to take in your url pattern and an object that maps to the params of the url called generatePath

https://v5.reactrouter.com/web/api/generatePath

import { generatePath } from "react-router";

generatePath("/user/:id/:entity(posts|comments)", {
  id: 1,
  entity: "posts"
});
// Will return /user/1/posts

So used in your example would be

<Link to={generatePath(MY_ROUTE, {userId: 1})} />
Category answered 10/3, 2022 at 21:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.