A. L
A. L

Reputation: 12649

react router relative link does not link properly

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

Answers (4)

Bear-Foot
Bear-Foot

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

Ozan
Ozan

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

Amr Aly
Amr Aly

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

Necmttn
Necmttn

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

Related Questions