ReactJS No routes matched location because of question mark in query string - reactjs

Hello I have a react app with this route, I use react-router-dom.
<Route path='/contacts?page=:page' element={} />
And I navigate like that:
navigate(/contacts?page=${newPage});
but because of question mark, in the console appears "No routes matched location", when I change the question mark with other symbol for example _ everything is fine.
Do you know how to resolve this problem?

There is a couple of solutions for this
Solution 1
You could try with parameters like this
<Route path="/contacts/page/:page" component={} />
And navigate like this
navigate(/contacts/page/${newPage});
Solution 2
If you want to work with query strings, with question mark you dont have to mention it in your simply add the query string (?page) and access it later like I did in this example
Example
<Route path='/contacts' element={} />
Navigate between pages the same way
navigate(/contacts?page=${newPage});
But you will have to access the page query string like this
import {useLocation} from "react-router-dom";
const location = useLocation();
console.log(location);
return (
<div>
<h1>Page</h1>
<p>{new URLSearchParams(location.search).get('page')}</p>
</div>
Hopefully this helps, but I'd recomend to go with the first solution

Related

react router v6 doesn't work if a question mark is attached to url [duplicate]

This question already has answers here:
React-router-dom v6 params
(2 answers)
Closed 9 months ago.
So the situation i'm in , i have a link that's sent through our backend to the user which he tries to access to reset his password , that link's path is : https://randomwebsite.com/reset-password/?uidb64=value&token=value
my route component and 404 route component look like this:
<Route
path="/reset-password/?:uidb64:token"
element={<ResetPasswordCodeConfirmation />}
/>
<Route path="*" element={<Error404Page />} />
if i try to visit the link above ( https://randomwebsite.com/reset-password/?uidb64=value&token=value) i get to the 404 page , if i remove the question mark from both my route and link , it works out fine and the link goes to the reset password component but i need to tell react router that it needs to accept a question as this is the link that's getting to the user , any idea ?
There is two different things here:
Query params (Which your backend has for this end points) and it means adding values after the ? character with & if you have multiple values
Route params (Which you attempted to add in your route component using the character :) and it means actually a totally different route with / separating it, for ex: <Route path="/reset-password/:token" /> means all https://randomwebsite.com/reset-password/AnyThingHereThatYouCanAccessLaterAsToken
So, your link should remain the same, and your Route component should look like this:
<Route
path="/reset-password"
element={<ResetPasswordCodeConfirmation />}
/>
I think this link has a good example of the same situation.
You don't need to add the question mark to the route path. React Router automatically parses the query parameters, and then you can use and validate the query params, like so:
import { useSearchParams } from 'react-router-dom'
...
const [queryParams, setQueryParams] = useSearchParams()
if (!queryParams.uidb64 && !queryParams.token) {
return <h1>Error</h1>
}
...
Or something like that. That's just an example.

How do I make a url contain multiple sections? React

So full disclosure, I'm not sure how to ask this question properly, but I do have a decent example. I'm making a React app and I'm trying to make the url more "descriptive" I suppose.
So it starts off at Home, then I go to a Products page and the url changes from /home to /products. This part is fine.
When I want to go to a specific product from the product page, I want the url to change to /products/example instead of just /example. Do I have to specify this with the Links or is there some cleaner way to get it done?
Right now my only answer is to make the link go to /product/example and have the App.js route to the same url. I'm not sure how to properly ask this question for a Google search so I had to ask it here. If you have an idea how to specifically phrase what I'm asking, I'd appreciate that too.
Thanks in advance.
I believe the example in your URL /products/example is the product name for your product. If so, this can be done in putting the product name as an URL parameter using react-router or react-router-dom if you still have not.
by declaring the route as
import { Switch, Route } from "react-router-dom";
const Router = () => (
<Switch>
<Route exact path="/home" component={()=>return <h1>Home</h1>} />
<Route exact path="/products" component={()=>return <h1>Products</h1>} />
<Route path="/products/:productName" component={props=>return <h1>props.match.params.productName</h1>} />
</Switch>
);
export default Router;
more on that here

ReactJS Values In The URL Always Visible

I have a filter system for my products in ReactJS which basically has the following:
http://localhost:3000/category/women/subcategory/tops/sorting/null/price/null/size/null/color/null/brands/null/merchants/null
The Route is as follows:
<Router>
<Route path="/category/:cat/subcategory/:subCat/sorting/:sorting/price/:price/size/:size/color/:color/brands/:brands/merchants/:merchants" component={Products} />
</Router>
The Problem is that I want to show filters in the URL in when they have a value other than null. Current my component works but I have to display every single filter in the URL with a null value by default, this is causing my URL to be extremely long. The only way I thought possible was to do a permutation combination of all the possible URLs in the filter and direct them all to { Products } which is extremely silly. There must be something in the Router component that I'm missing?
You need to use optional params in this case.
As and example if you want to accept both sorting/ascending/price and sorting/price you can write your path as follows assuming you use react router v4.
<Router>
<Route path="sorting/:sort?/price" component={Products} />
</Router>
You can read more about this here: React Router with optional path parameter

React-router child-route navigation not working

I'm trying to follow the react-router tutorial here trying to navigate using a child route and it doesn't work.
For example given this route definition:
export default <Route path="wifi" component={ Wifi }>
<IndexRoute component={WifiView}/>
<Route path="list" component= {WifiListView}/>
<Route path="connect" component={WifiConnectView}/>
</Route>;
If we are on "/" and navigate to "/wifi" we are good. The WifiView is presented however if if from "/wifi" we call hasHistory.push('list') it doesn't find the route. I would assume that the route is relative to its current location since I'm not using the "/" but that isn't being respected.
Also the document said:
You can also use the router that Router provides on "context". First,
you ask for context in the component, and then you can use it...
But I don't see anything that mentions how to do that in TypeScript so I'm using the static hashHistory.
It looks like novice questions but I had nowhere to ask since the suggested Discord channels are all dead... Can anyone help with those?
Thanks! Appreciate any help!
Ok finally found the replies to my questions...
As for today, react-router don't support relative navigation which means, it hast to navigate to the whole chain of routes and that is why hasHistory.push('list') doesn't work.
In order to get the context.router we need to use withRouter high order component but that isn't exposed on the TypeScript definition files they provide.

react-router: how to get the previous route in onEnter handler?

I'm trying to find a way to read the previous route/path when a user hits a new one, within the onEnter handler.
I have a React Router structured like so:
<Router history={history}>
<div className="index">
<Route
path="/"
component={ComposedAppComponent}
onEnter={this.onEnterHandler.bind(this)}
>
<Route name="streamKey" path=":streamKey">
<Route name="articleUri" path="(**)" />
</Route>
</Route>
</div>
</Router>
the function, onEnterHandler, looks like so:
onEnterHandler(nextRouteState) {
const { streamKey, splat } = nextRouteState.params;
const nextPath = `/${streamKey}/${splat}`;
const prevPath = // HOW DO I GET THE PREVIOUS PATH?
}
I can't seem to find a way to read the previous route path the user was on... I need to make a comparison between the new route and previous one. Any input on how to approach this is much appreciated. :)
Cheers!
Are you trying to get the previous path when the user navigate to new path through address bar or using react-router like this.context.router.push()?
If the navigation is using react-router, maybe these simple way would get what you're looking for:
1. Pass prevPath using query-params
Navigation might look like this:
`<Link to="/next" query={{ prevPath: this.props.location.pathname }}> Your Next path</Link>`
Now, you can get your prevPath value on onEnterHandler method by using this:
nextState.location.query.prevPath
Cons: the query will appear on address bar.
Pros: you are still able to get your prevPath when user is navigating through address bar (direct path access).
2. Pass prevPath using state
Navigation might look like this:
`<Link to="/next" state={{ prevPath: this.props.location.pathname }}> Your Next path</Link>`
Now, you can get your prevPath value on onEnterHandler method by using this:
nextState.location.state.prevPath
Cons: the query won't appear on address bar.
Pros: you are not able to get your prevPath when user is navigating through address bar (direct path access).
In addition, the cons of those method is you should assign a prevPath value into each of Link components. Create a wrapper component for the Link component would solve this issue.

Resources