Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Router - How to replace dynamically parameters in a string

I have a set of dynamically parameters in the URL, ad example the user locale, that looks like that:

/en/homepage

In my router config JSON file, I have something like:

/:locale/homepage

Which is the best way in order to replace these parameters directly in React Router?

I've come up with this solution that looks to me very far away from a standard or portable solution:

const urlTemplate = '/:language/homepage';
const mappedUrl = pathToRegexp.compile(urlTemplate);
const url = mappedUrl({
  'language': this.props.match.params.language
})
this.props.history.push(url);

I'm able to retrieve the match parameters if the component is wrapped by withRouter ( HOC from React router ) and replace them with pathToRegexp (🐾 pillarjs/path-to-regexp ), but if I need to use <Link to={}> in a stateless component it's very annoying.

Are there standard solutions in order to do that?

Thank you in advance :)

like image 543
AnnamariaL Avatar asked Dec 22 '17 17:12

AnnamariaL


People also ask

How do you update parameters in react?

Use the useSearchParams hook to programmatically update query params in React router, e.g. setSearchParams({query: 'myValue'}) . The useSearchParams hook is used to read and modify the query string in the URL for the current location.

How do you pass optional parameters in react Router?

To add in an optional path parameter in React Router, you just need to add a ? to the end of the parameter to signify that it is optional. And then in your component you could access the GET parameters using the location.search prop that is passed in by React Router.

How do you pass query parameters in react?

To pass in query parameters, we just add them to the Link s to props as usual. For example, we can write the following: We first defined the useQuery Hook to get the query parameters of the URL via the URLSearchParams constructor. We get the useLocation() s search property.

What is the difference between HashRouter and BrowserRouter in react?

Both BrowserRouter and HashRouter components were introduced in React Router ver. 4 as subclasses of Router class. Simply, BrowserRouter syncs the UI with the current URL in your browser, This is done by the means of HTML-5 History API. On the other hand, HashRouter uses the Hash part of your URL to sync.


2 Answers

I used React Router's generatePath to update the path /map/:zoom/:lon/:lat/ when a user changes a Leaflet map view. Note that in my case I replaced the path rather than pushing it.

import { generatePath } from 'react-router';

function updatePath(lat, lon, zoom) {
  const path = generatePath(this.props.match.path, { lat, lon, zoom });
  this.props.history.replace(path);
}
like image 133
Leila Hadj-Chikh Avatar answered Sep 17 '22 11:09

Leila Hadj-Chikh


I use a function that replaces the parameters of the route path with the arguments of the function using regex.

If a route is:

'/:language/homepage'

the function will replace :language with the parameter passed to the function.

Function

This is the function to replace the values in the path:

function getRoute(path) {
    let args = Array.prototype.slice.call(arguments, 1);
    let count = -1;
    return path.replace(/:[a-zA-Z?]+/g, function (match) {
        count += 1;
        return args[count] !== undefined ? args[count] : match;
    });
};

The key here is the regex /:[a-zA-Z?]+/g that only match strings that start with : and include any character between a-z and A-Z meaning that when the next / is found, it will finish the match, so it will replace all params defined like this.

This works for my specific usage of simple params, but if you need to add more characters to the matching regex you can do so (like numbers, underscores, etc).

Usage

It is used like this:

let newPath = getRoute('/:language/homepage', 'en');

and the result will be:

'/en/homepage'

Link example

It can be used for Links like this:

<Link to={ getRoute('/:language/homepage', 'en') }>

Multiple parameters in route

It accepts multiple parameters as well:

getRoute('/:id/:language/homepage/:value', 123, 'en', 'myVal')

this will return:

'/123/en/homepage/myVal'
like image 29
c-chavez Avatar answered Sep 18 '22 11:09

c-chavez