Add fixed string to the end of route parameter - javascript

I am using React Router v6.4.1 and would like to have a consistent ending to a set of dynamic routes.
For instance, I would like my product detail routes to ends with "-product".
Say I have a path like "/shaver-900-product". This should trigger my ProductDetails component which could then use "shaver-900" to get the product details from my API.
I've tried defining the path using the following, but I cannot get this working:
<Route path=":productSlug-product" element={<ProductDetails />} />
If the product slug in the API/Database changes to have "-product", then this would work:
<Route path=":productSlug" element={<ProductDetails />} />
However, I would prefer to not change the database and only make the changes to how the routes are matched.

react-router-dom#6 route paths no longer handle any sort of regex patterns for path matching, the path parameters are effectively all or nothing. Use the productSlug param and handle the string manipulation in the matched routed component.
<Route path=":productSlug" element={<ProductDetails />} />
Path is "/shaver-900-product".
const ProductDetails = () => {
const { productSlug } = useLocation();
... logic to extract "shaver-900" from productSlug ...
...
};

Related

React Router alias naming route

I have route in version "react-router-dom": "^6.7.0"
<Route path="/categories" element={<Categories />} />
I am navigating to this "/categories" route on multiple pages with
onClick={() => {
return navigate("/categories");
}}
Now my concern is that if my route path <Route path="/categories" changes in future to <Route path="/categories-abcde" then I will have to change everywhere in program navigate("/categories") to navigate("/categories-abcde").
Is there any name aliasing like <Route path="/categories" element={<Categories />} alias='somename' /> that I can use everywhere in navigate("/somename"). So that if route path <Route path="/categories" changed then I do not have to change in navigate("/somename") everywhere.
A feature like this doesn't exist in react-router but doing a global search and replace is a very trivial action. Search and replace can be prone to typos though, either there's a typo on a specific target path so it doesn't get replaced, or the person making the change typo replaces all the target paths.
To resolve this issue the solution is also trivial, store all the route paths in a configuration object.
Example routes.types.js:
export const ROUTES = {
...
CATEGORIES: "/categories",
...
HOME: "/",
...
};
Usage:
<Route path={ROUTES.CATEGORIES} element={<Categories />} />
onClick={() => {
navigate(ROUTES.CATEGORIES);
}}
Now when the route path needs to be updated it is updated in one location where it's declared and all instances of its usage automatically read the updated value.
No, React Router doesn't have an alias like property.
There are multiple ways to tackle this, eg:
Add a single point where the name is returned
# Define
export const getCategoriesNavigator = () => navigate("/categories");
# Use
onClick={getCategoriesNavigator}
Should your route change, you only have to change a single point
Match them all!
You could extend your route to path="/categories*" (note the *)
This way stuff like your example, /categories-abcde will still be captured by that route, so no need to change any navigate()

react router 6.4.3 nested routes with two different routes pointing to one route/component

Greeting,
I am make a website to display different products.
Assume I have the following routes:
perfume/a-specific-perfume
base/a-specific-base
These routes both display a single page with a single product, which is nice, but what if I have many different type of product. This would lead me to have the following routes:
perfume/a-specific-perfume
base/a-specific-base
water/...
.../...
It leads to repetitive works for each type of product.
Is there a way to ignore the root route? I tried using a wild card, "*/a-specific-perfume" or "*/p/a-specific-perfume", and it did not work. Any suggestion?
In react-router-dom#6 the wildcard character "*" is only valid at the end of a path and only serves to indicate that a route component can render descendent routes. You can use route path params for dynamic path segments.
Examples:
<Route path="/:type/a-specific-perfume" element={....} />
<Route path="/:type/a-specific-base" element={....} />
<Route path="/foo/:type/a-specific-perfume" element={....} />
<Route path="/bar/:type/a-specific-base" element={....} />
In each component (the element prop) use the useParams hook to access the route param value.
"/perfume/a-specific-perfume"
"/base/a-specific-base"
"/water/..."
"/.../..."
import { useParams } from 'react-router-dom';
...
const { type } = useParams(); // "perfume"|"base"|"water"|"..."|etc...

How to check for a randomly generated url that begins with a phrase with Route hook in reactjs

I am trying to setup a website where you can register people and it will add their information to a database. You can then search for these people's names on the main page and it will filter results depending on name. Each name that pops up that is similar to the searched string will be a Link hook from reactjs and it will take you to a page with the pathname of:
"/student_info_"+element
And on this page will have the person's information. I am having trouble rendering the page on the App.js as it generates partially random url and the code I have in my App.js is :
return (
<div>
<Switch>
<Route path="/" exact>
<MainPage />
</Route>
<Route path="/register_student">
<RegisterPage />
</Route>
<Route path="/student_info_">
<StudentInfo />
</Route>
</Switch>
</div>
);
This doesn't seem to work for whatever reason. I test this as in the student info page I include:
return (
<div className="btn-textfield">
{pathName}
</div>
);
And when I am on the student info page it does not show any information. I am fairly certain the issue is in the App.js checking the pathname of the url and displaying the correct page, but I am not sure exactly how to fix it. I appreciate any responses.
I believe you are looking for route parameters.
In App.js you could do:
<Route path="/student_info/:id">
<StudentInfo />
</Route>
Then inside the StudentInfo component you could get the :id part of the current route like this:
import { useParams } from "react-router-dom";
...
const { id } = useParams();
return (
<div className="btn-textfield">
{id}
</div>
);
If you want the paths to look exactly like /student_info_%ID%, you can also achieve it using the same approach & treating this whole part of the path as an :id.

How to make same URL scheme but different route and component in React JS

I have some dynamic and static URLS, I am ibiut but confused how to call different component on same route structure, pleas have a look below
**Required Routes structure: **
https://example.com/:pagename (dynamic)
https://example.com/:countryname (dynamic)
https://example.com/about-us (static)
Current Route:
<Route path='/:pageName' component={Page} exact />
<Route path='/:countryname' component={Country} exact />
<Route path='/about-us' component={AboutUs} exact />
Thanks
The better way to do this is to change your URL logic as follows:
https://example.com/page/:pagename or https://example.com/p/:pagename
https://example.com/country/:countryname or https://example.com/c/:countryname
and the Routes:
<Route path='/page/:pageName' component={Page} exact />
<Route path='/country/:countryname' component={Country} exact />
The Route algorithm stops at the first URL-pattern that matches the query. Consider the following two URLs:
https://example.com/homepage
https://example.com/germany
Both of these URLs match the first pattern (https://example.com/:pagename) as the matching algorithm won't know that "germany" is not a pagename.
If you can't go this way you could build a sub-routing component which checks whether the first parameters after example.com matches any country name or any page name and based on that render the corresponding component:
<Route path='/:pageNameOrCountryNameNotSure' component={SubRouter} exact />
However, this is not a clean solution and is not recommended.

How do I create `/orders/:id/detail` path in react-router

I would like to create a path /orders/{order_id}/detail using react-router. How do I do this on the <Route /> component and also when using the <Link /> to navigate to the path.
Currently I have it like this
<Route exact path='/orders/:id' component={OrderDetails} />
but I want it like this
<Route exact path='/orders/:id/detail' component={OrderDetails} />
Any help appreciated.
this route:
<Route exact path='/orders/:id/detail' component={OrderDetails} />
is correct, its going to render the OrderDetails component on this uri:
/orders/whatEverId/details
the point is the navigation to this url to render that component, for that you need to know that every component that rendered with react router directly has three extra props, location, match and history, and you can get them from this.props automatically if you are using class based components, if you are using function component you need to use their hook called useParams hook that react-router provides and ddestructure the parameter that you want from url.
more info is here

Categories

Resources