Mohit Ashliya
Mohit Ashliya

Reputation: 635

react router giving sub path for clicking again on link --v6

here I am building a website and I am using react-router-dom everything seems to work fine when I use the Navbar and Footer components in every page. So I come up with idea to wrap the component in a wrapper which contains Navbar and Footer.

When I click on Link or maybe NavLink, it seems to work fine but when I click again on same or another link in navbar then it navigates to a sub path under the previous selected path. like this
on Single Click:

http://localhost:3000/projects

on clicking the same link again:

http://localhost:3000/projects/projects

App.js

import './App.css';
import {BrowserRouter as Router, Route, Outlet, Routes} from 'react-router-dom'
import {CommonScreen, Wrapper, About, Email, Projects} from './Barell'

function App() {
  return (
    <>
    <Router>
      <Routes>
        <Route  index  element={<Wrapper children={<CommonScreen/>}/>}/>
        <Route  path='about'  element={<Wrapper children={<About/>}/>}/>
        <Route  path='projects'  element={<Wrapper children={<Projects/>}/>}/>
        <Route  path='email'  element={<Email/>}/>
      </Routes>
    </Router>
    <Outlet/>
    </>
  );
}

export default App;

Navbar.jsx:

import React from 'react'
import '../../index.css'
import { NavLink } from 'react-router-dom'

const links = [
  {
    name:"Home",
    slug:"/",
  },
  {
    name:"Projects",
    slug:"projects",
  },
  {
    name:"About",
    slug:"about",
  },
  {
    name:"Contact",
    slug:"email",
  },
]
export const Navbar = () => {

  let activeStyle = {
    textDecoration: "underline",
  };


  return (
    <>
      <nav>
        <div id='brand'>Prema<span>culture</span></div>
        <ul id='links'>
         {
          links.map((current,index) => (
            <li>
              <NavLink 
              key={index}
              to={current.slug}
              style={({ isActive }) =>
              isActive ? activeStyle : undefined
            }
              >
                {current.name}
              </NavLink>
            </li>
          ))
         }
        </ul>
      </nav>
    </>
  )
}

Wrapper.jsx:

import React from 'react'
import { Navbar, Footer } from '../Barell'

export const Wrapper = ({children}) => {
  return (
    <>
    <Navbar/>
    {children}
    <Footer/>
    </>
  )
}

Upvotes: 2

Views: 739

Answers (1)

Drew Reese
Drew Reese

Reputation: 202618

You are using relative paths (versus absolute), so when already on a route, say "/projects", and then click a link that navigates to "about", the code links relative from "/projects" and results in "/projects/about".

To resolve you can make all the link paths absolute by prefixing a leading "/" character. Absolute paths begin with "/".

Example:

const links = [
  {
    name:"Home",
    slug:"/",
  },
  {
    name:"Projects",
    slug:"/projects",
  },
  {
    name:"About",
    slug:"/about",
  },
  {
    name:"Contact",
    slug:"/email",
  },
];

Additionally, to make the code more DRY you might also want to convert the Wrapper component into a layout route. Layout routes render an Outlet component for nested routes to be rendered into instead of a children prop for a single routes content.

Example

import React from 'react';
import { Outlet } from 'react-router-dom';
import { Navbar, Footer } from '../Barell';

export const Layout = () => {
  return (
    <>
      <Navbar/>
      <Outlet />
      <Footer/>
    </>
  )
}

...

function App() {
  return (
    <>
      <Router>
        <Routes>
          <Route element={<Layout />}>
            <Route path="/" element={<CommonScreen />} />
            <Route path='about' element={<About />} />
            <Route path='projects' element={<Projects />} />
          </Route>
          <Route path='email' element={<Email />} />
        </Routes>
      </Router>
      <Outlet />
    </>
  );
}

Upvotes: 1

Related Questions