Reputation: 12649
So I'm using the npm package react-router-relative (https://www.npmjs.com/package/react-router-relative) but it doesn't seem to be switching the url properly.
Here's what my links looks like:
<Link to='items' className="btn btn-default submission-button">Items</Link>
<Link to='maps' className="btn btn-default submission-button">Maps</Link>
Here's my routing:
<Route path="submissions" component={SubmissionPage}>
<Route path="items" component={ItemSubmissions}></Route>
<Route path="maps" component={MapSubmissions}></Route>
</Route>
what happens is the first time I click on the link it'll link properly i.e.
http://localhost:3000/#/account/submissions/items
but when I hit it again it'll go to:
http://localhost:3000/#/account/submissions/items/items
at this point the end part will switch rather than append, but throws an error.
However, I'm trying to make the part right after 'submission' switch, i.e. account/submissions/items
account/submissions/maps
.
What am I doing wrong?
I've tried a non-relative link variation of this, i.e. {this.props.location.pathname + '/items'}
but it just does the same thing.
Upvotes: 16
Views: 10658
Reputation: 774
First, let's emphasis on the concept of relative link. It is a link that will bring you somewhere depending on where you already are.
Meaning, result will vary if you use the same relative link in different places (URLs). The direct implication is that if you want only one given behaviour for a relative link, you cannot use it at several places.
What happens in your case is that the same relative link appears for different URLs, leading to different results.
What can you do:
As pointed earlier, you could use currentPath
props, suggested in the page you linked here.
The result would be something like:
<Link to='items' currentPath='/submissions'>Items</Link>
<Link to='maps' currentPath='/submissions'>Maps</Link>
Which looks like a disguised absolute path:
<Link to='/submissions/items'>Items</Link>
<Link to='/submissions/maps'>Maps</Link>
A solution for relative paths would be:
<Link to='../items'>Items</Link>
<Link to='../maps'>Maps</Link>
But keep in mind that those links, being relative, should only be displayed in one place, in your case #/submissions/somewhere
If you want a link that brings you to the same page regardless of the current location, you should use absolute links.
So far, I haven't come up with many uses for relative links.
Go back: <Link to="..">Go back</Link>
Or maybe common actions: <Link to="./edit">Edit</Link>
To conclude, I would say that there is no need for relative links when only one behaviour is expected. One behaviour means one route, and if you know the route, you might as well use an absolute link. Relative links should be used only when you expect different behaviours.
Upvotes: 6
Reputation: 1762
I was not able to find any other approach but this. Unfortunately react-router doesn't support the relative paths but the work around would be using the Switch and then generating absolute paths in your components if it is suitable for your use. You have to update your react-router to 4+ before importing the Switch method.
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
<Router>
<Switch>
<Route path="submissions" component={SubmissionPage} />
<Route path="items" component={ItemSubmissions} />
<Route path="maps" component={MapSubmissions} />
</Switch>
</Router>
But probably if I were to use only two path as you are doing which ends up being /accounts/submissions/items and /maps I would probably just stick with the <Route path="/accounts/submissions/items" component={MapSubmissions} />
P.S : I am just pointing out my approach and solution. I am not sure whether it would cause other problems or not.
Upvotes: 1
Reputation: 3905
I have searched for your problem and i found this useful package react-router-relative-links
To install it run in your terminal :
npm install react-router-relative-links react-router-apply-middleware
then in you routes file you will apply the middleware like so:
import { Router, Route, browserHistory } from 'react-router';
import applyMiddlewareRouter from 'react-router-apply-middleware'
import { useRelativeLinks } from 'react-router-relative-links'
<Router history={browserHistory} render={applyMiddlewareRouter(useRelativeLinks())}>
<Route path="submissions" component={SubmissionPage}>
<Route path="items" component={ItemSubmissions}></Route>
<Route path="maps" component={MapSubmissions}></Route>
</Route>
</Router>
then any time you you need to add a navigate Link you can add it like so:
we will assume the current path is localhost:8080/account/submissions
<RelativeLink to='./items'>test</RelativeLink> # to localhost:8080/account/submissions/items
<RelativeLink to='./maps'>test</RelativeLink> # to localhost:8080/account/submissions/maps
, However it's better to use the Link component provided by react-router
Upvotes: 4
Reputation: 1277
if you pass currentPath
props to your link it will start work. otherwise, if you don't define the current path. it falls to window.location.hash
which is not good.
<Link to='/items' currentPath='/submissions' className="btn btn-default submission-button">Items</Link>
<Link to='/maps' currentPath='/submissions' className="btn btn-default submission-button">Maps</Link>
I believe the npm package react-router-relative
is a bit buggy.
personally, I don't recommend you to use in production.
Upvotes: 2