Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

The URL changes but component is not rendered when using React Router Dom v6 route in nested page of my react application

I have a main page with a sidebar and a content displaying area which will display the selected option. The problem occurs when I try to click on the Link in sidebar, it doesn’t changes anything in the content displaying division but URL changes. If I define the routes in App.js then Link works but it opens the component in new page, I want it to be displayed in the MainPage.js itself.

App.js:

import { useEffect, useState } from 'react';
import {
  BrowserRouter as Router,
  Route,
  Routes,
  Navigate
} from 'react-router-dom'; 
import LoginPage from './pages/LoginPage';
import MainPage from './pages/MainPage';
import SamplePage from './pages/SamplePage'

const App = () => {
  /** HOOKS */

  const [admin, setAdmin] = useState({name: "junaid"})
  // const [admin, setAdmin] = useState(null)

  // hook to see if admin is already logged in
  useEffect(() => {
    const loggedAdmin = window.localStorage.getItem('loggedProSkillzAdmin')
    if (loggedAdmin) {
      setAdmin(JSON.parse(loggedAdmin))
    }
  })

  return (
    <Router forcerefresh={true}>
      {/* <Navigate from="/" to={admin ? "/main" : "/login"} /> */}
      {/* <Navigate exact from="/" to="/main" /> */}
      <Routes>
        {admin === null ? (
          <Route path="*" element={<LoginPage setAdmin={setAdmin} />} />
        ) : (
          // If admin is logged in, navigate to MainPage
          <>
            {/* Redirect from root to /main */}
            <Route path="/" element={<Navigate to="/main" />} />
            <Route path="/main/*" element={<MainPage />} />
          </>
        )}
        <Route path="*" element={<p>No Path Found</p>}/>
      </Routes>
    </Router>   
  )
}

export default App;

MainPage.js:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import { Route, Routes, Link} from 'react-router-dom';
import { MdDashboard } from "react-icons/md";
import { IoIosSettings } from "react-icons/io";
import { FaUsers, FaUserAstronaut } from "react-icons/fa";
import Sidebar from "../components/Sidebar"
import SidebarItem from "../components/SidebarItem"
import SamplePage from './SamplePage';

const MainPage = () => {
  return (
    <div className='flex w-full h-full'>
      <Sidebar>
        <SidebarItem icon={<MdDashboard/>} text="Dashboard" path="dashboard" active={true}/>
        <SidebarItem icon={<FaUsers/>} text="Users" path="users" active={false}/>
        <SidebarItem icon={<FaUserAstronaut/>} text="Providers" path="providers" active={false}/>
        <SidebarItem icon={<IoIosSettings/>} text="Settings" path="settings" active={false}/>
      </Sidebar>
      <div className='w-full h-dvh bg-black'>
        <Routes>
          <Route path="/main/dashboard" Component={<SamplePage title={"Dashboard"} index/>}/>
          <Route path="/main/users" element={<SamplePage title={"Users"}/>}/>
          <Route path="/main/providers" element={<SamplePage title={"Providers"}/>}/>
          <Route path="/main/settings" element={<SamplePage title={"Settings"}/>}/>
        </Routes>
      </div>
    </div>
  )
}

export default MainPage

SidebarItem.js:

import { useContext } from "react"
import { SidebarContext } from "./Sidebar";
import { IoSettings } from "react-icons/io5";
import { Link } from "react-router-dom";

const SidebarItem = ({ icon, text, path, active }) => {
  const { expanded } = useContext(SidebarContext)

  return (
    <>
      <Link
        to={`/main/${path}`}
        className={`
          relative flex items-center py-2 px-3 my-1
          font-medium rounded-md cursor-pointer
          ${active
            ? "bg-indigo-800 text-white"
            : "hover:text-white hover:bg-indigo-800 "
          }
        `}
      >
        <div>{icon}</div>
        <span className={`
          overflow-hidden transition-all
          ${expanded? "w-52 ml-3 visible":"w-0 invisible"}
        `}>
          {text}
        </span>
      </Link>
    </>
  )
}

export default SidebarItem

SamplePage.js:

const SamplePage = ({ title }) => {
  console.log('Sample page works for ', title)

  return (
    <div className="bg-red-700 w-full h-full">
      {title}
    </div>
  )
}

export default SamplePage

Before Clicking the Link

After clicking the Link(notice url changes)

Expecting somehow the component renders in the MainPage.js

>Solution :

Issue

Descendent routes build relative to the parent route. MainPage is rendered on path "/main/*":

<Route path="/main/*" element={<MainPage />} />

But is including another "main" path segment in its descendent routes:

<Routes>
  <Route
    path="/main/dashboard"
    Component={<SamplePage title="Dashboard" index />}
  />
  <Route path="/main/users" element={<SamplePage title="Users" />} />
  <Route path="/main/providers" element={<SamplePage title="Providers" />} />
  <Route path="/main/settings" element={<SamplePage title="Settings" />} />
</Routes>

This means the URL path is actually "/main/main/dashboard", etc.

Solution

Remove the extraneous "main" path segment from the descendent routes. Be sure to correctly use the element prop instead of Component since you are not using a Data router.

<Routes>
  <Route path="/dashboard" element={<SamplePage title="Dashboard" />} />
  <Route path="/users" element={<SamplePage title="Users" />} />
  <Route path="/providers" element={<SamplePage title="Providers" />} />
  <Route path="/settings" element={<SamplePage title="Settings" />} />
</Routes>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading