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()
Related
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...
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 ...
...
};
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
I'm migrating a react application and I'm trying to split it. Basically, I would like to redirect some client-side react routes to absolute urls (or relative, but at least go with a server roundtrip, where reverse proxying is done)
Note that
react-router 3.0.0
react-router-redux 4.0.7
The app have these urls
http://myhost/ => homepage
http://myhost/someroute1 => a first route
http://myhost/someroute2 => a second route
http://myhost/someroute3 => a third route
Everything is inside react right now.
Routing looks like this :
<Provider store={store}>
<Router history={history}>
<Route path="/" component={Root}>
<IndexRoute component={Home} />
<Route path="/someroute1" component={Route1} />
<Route path="/someroute2" component={Route2} />
<Route path="/someroute3" component={Route3} />
</Route>
</Router>
</Provider>
The goal is to redirect, say, routes "/" and "/someroute2" to static urls (server urls). As so :
http://myhost/ => http://anotherhost/
http://myhost/someroute1 => keep react routing
http://myhost/someroute2 => http://anotherhost/anotherroute5
http://myhost/someroute3 => keep react routing
The question is simple : is is possible to replace, in a clean way, a react router route with an absolute url ?
I heard about Redirect and IndexRedirect components, but I can't figure how to use it properly, and, due to a lack of react / react-router, I can't figure if there would be any dangerous side-effects (in history for example).
Use Route's render prop instead of component. That way, you can specify a function to be called instead of a component to be instantiated. In the function, perform the navigation the old-fashioned way, using window.location.href:
<Route
path="/someroute2"
render={() => {
window.location.href = "http://anotherhost/anotherroute5";
return null;
}}
/>
Partially based on #brub answer, I've found a solution using a dumb component.
import React, { Component } from 'react'
export default class MyRedirectRoute extends Component {
componentDidMount() {
window.location.href = //my url here
}
render() {
return null
}
}
That I pass like this
<Route path="/someroute3" component={MyRedirectRoute} />
Though, I'm still not aware of a few things :
Is this a recommended solution ?
Are there any history side-effect ?
Is there any better (more react-router) solution than window.location.href ? I tried this.context.history without any success...
I'm waiting for feedback / better solution before accepting my own answer
You probably don't need React Router for this. The creator of React Router suggests using the <a> tag.
I haven't tried it but syntactically you could do it like this:
<Route
path="/someroute2"
render={() => <Redirect to="http://anotherhost/anotherroute5" />}
/>
I'm attempting to migrate an application from a custom library to react/redux. I'm investigating using react-router as our top-level routing tool.
I'm planning on using hashHistory as our existing route tree is done entirely in hashes. However, our existing route tree does not include a leading slash after the #.
In order to not break all our existing links, I'm wondering if there is a way to omit the leading slash.
So far, I've attempted:
import {createHashHistory} from 'history'
const custom_history = useRouterHistory(createHashHistory)({
hashType: 'noslash'
})
class Router extends Component {
render() {
return (
<Router history={custom_history}>
<Route path="" component={Container}>
<Route path="dashboard" component={SubContainer} />
</Route>
</Router>
)
}
}
But using createHashHistory directly from the history library appears to cause an error in the second nested getCurrentLocation call of history.listen.
Is there a means to do this in react-router ^3.0.0?