I encountered a problem with React Router v4 Switch component. I'm quite surprised that i couldn't find a relevant thread for this problem. A common Switch will look like this:
<Switch>
<Route path='/path1' component={Path1Component}/>
<Route path='/path2' component={Path2Component}/>
<Route exact path='/' component={Home}/>
<Route component={NotFound}/>
</Switch>
This means that when i'm on a path: '/' i get a Home component, on '/path1' i get a Path1Component and on path '/foobar' i get a NotFound component. And that is perfectly fine
However when i'm on '/path1/foobar' route i also get the Path1Component. This behaviour is not correct in every case - this time i do not want any nested routes for '/path1' route. '/path1/foobar' should get a NotFound component, any string, with '/' or without after '/path1' should return NotFound component.
What would be the preferred resolution to this problem? I could just add exact to every path, but wouldn't that be overbloating the code? I feel like that should be the default, but it's not the case.
Even on React Router v4 docs, like here. I see this problem - here '/will-match/foo' will also match. What are your thoughts?
There is a discussion here, but to make it short : it would break existing code. If this were to change, you'd have to do exact={false} if you want to match child routes without doing 'path1/child1'.
Related
How does the two path differ . I tried going through the docs of react router but it still creates confusion .
First one is
<Route
path="/cricket/:description/:id"
component={xyz}
/>
and another is
<Route
exact
path="/cricket"
component={xyz1}
/>
I see that the first Route is mentioned in App.js .It leads to confusion as which one got executed and how ?
Router will render both componenets if path is something like /cricket/foo/123 because it matches both pattern.
If you want only one to render you have to use exact prop like
<Route exact path="/cricket"
component={xyz1}
/>
I have a case in react router v4:
<Route path="/:time?/:zone?" component={TimeComponent} />
However I don't want to render that TimeComponent if route is:
/user/userId123
As you can see above, the path matches user as :time and userId123 as :zone.
My goal: I don't want path to match if route contains /user.
I know I can use regex, but how to specify that I dont want to match the path if contains /user?
Looking for help
You can use switch from react router dom like this:
<Switch>
<Route path="/user/:userId?" component={UserComponent} />
<Route path="/:time?/:zone?" component={TimeComponent} />
</Switch>
With this it will match only one route at a time and you 2 param route is at the end. So using this approach you can catch /user route before time component route.
Please try this.
I just noticed that in react router (v3.x) a component unmounts and remounts if a path param changes. Is this the expected behaviour?
Route:
<Route path="/landing/register/:step" component={Register}/>
Now, lets say I am on route "/landing/register/personal-data" and I am navigating via <Link/> or router.push({...}) to the next registration step "/landing/register/address", the Register-component gets first unmounted and then mounted again, loosing all its state.
Is this the correct way or am I doing something wrong?
EDIT:
It seems that the problem is that I am using nested routes, where I use a component for the parent route.
This example works (not re-mounting Register-Comp on path param change):
<Route path="/landing">
<Route path="register/:step" component={Register}></Route>
</Route>
But when I use a component for the parent route, it doesnt (not re-mounting AppView-Comp, but Register-Comp on path param change):
<Route path="/landing" component={AppView}>
<Route path="register/:step" component={Register}></Route>
</Route>
I solve this problem by nesting routes in child components, like this:
// Router class
<Route path="/landing/register" component={Register}/>
//Register component
<BrowserRouter>
<div>
<Route path="/landing/register/personal-data" component={PersonalData}/>
<Route path="/landing/register/payment-data" component={PaymentData}/>
...other routes
</div>
</BrowserRouter>
But in this case i store user data in redux store instead of component state, however you can store it on your component state it is not problem.
Is it possible to do this with react router?
<Route path="/:reset_password" component={ResetPassword} />
<Route path="/:create_password" component={CreatePassword}/>
I want use different param with different component. I test above code and it doesn't work. the code above work if I change to this:
<Route path="/something1/:reset_password" component={ResetPassword} />
<Route path="/something2/:create_password" component={CreatePassword}/>
thanks for the help
As #chris said, remove the colons and/or assign dedicated routes. React Router can't differentiate between the two routes you've supplied, as they're technically identical (root path + a dynamic parameter.)
So, I currently have the following as part of my url map for react.
<Route path="dog" component={DogWrapper}>
<Route path=":id" component={DogDetails}/>
<Route path=":id/genealogy" component={Genealogy}/>
</Route>
But I'm never hitting the Genealogy component. Any ideas as to why?
Your issue is with ordering. React-router works on precedence so it will always take the :id route first. Move the geneaolgy route up and you should be all set.
https://github.com/reactjs/react-router/blob/master/docs/guides/RouteMatching.md#precedence