Search code examples
reactjsreact-routerfrontendreact-router-domvite

Is this correct configuration of react app using vite?


I have created a react app using vite.

This is my App.jsx

import './styles.css'
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Home from './components/Home'
import About from './components/pages/About'
import Resume from './components/pages/Resume'
import Work from './components/pages/Work'
import Contact from './components/pages/Contact'
function App() {
  return (
    <>
    <BrowserRouter>

        <Routes>
          <Route path='/' element={<Home/>}>
            <Route path='about' element={About}></Route>
            <Route path='resume' element={Resume}></Route>
            <Route path='work' element={Work}></Route>
            <Route path='contact' element={Contact}></Route>
          </Route>
        </Routes>

    </BrowserRouter>
     
    </>
  )
}

export default App

This is my Home.jsx

import NavBar from "./pages/NavBar";
import Header from "./pages/Header";
import { Outlet, useNavigate } from "react-router-dom";
import Profile from "./pages/Profile";
// import About from "./pages/About";
// import Resume from "./pages/Resume";
import Contact from "./pages/Contact";
import { useEffect } from "react";

function Home() {
  const navigate = useNavigate();
  useEffect(() => {
    navigate("/about");
  }, []);
  return (
    <>
      <Header></Header>
      <div className="d-flex1 gap-3">
        <Profile></Profile>
        <div className="w-100">
          <div className=" navbar d-flex justify-content-end">
            <NavBar></NavBar>
          </div>
          <Outlet />
          {/* <Resume></Resume> */}
          {/* <About></About> */}
          <Contact></Contact>
        </div>
      </div>
    </>
  );
}

export default Home;

This is my package.json enter image description here

This is My NabBar.jsx

import * as Lucide from "lucide-react";
import { NavLink, useLocation } from "react-router-dom";
function NavBar() {
  const location = useLocation();

  const activeLink = location.pathname.split("/").pop();

  return (
    <>
      <div>
        <div className="d-flex gap-3 card-effect mt-3 ">
          <NavLink
            to="/about"
            className={`icon  ${activeLink === "home" ? "active" : null}`}
          >
            <Lucide.HomeIcon></Lucide.HomeIcon>
            <p>Home</p>
          </NavLink>
          <NavLink
            to="/resume"
            className={`icon  ${activeLink === "resume" ? "active" : null}`}
          >
            <Lucide.FileTextIcon></Lucide.FileTextIcon>
            <p>Resume</p>
          </NavLink>
          <NavLink
            to="/work"
            className={`icon  ${activeLink === "work" ? "active" : null}`}
          >
            <Lucide.BriefcaseIcon></Lucide.BriefcaseIcon>
            <p>Work</p>
          </NavLink>
          <NavLink
            to="/contact"
            className={`icon  ${activeLink === "contact" ? "active" : null}`}
          >
            <Lucide.ContactIcon></Lucide.ContactIcon>
            <p>Contact</p>
          </NavLink>
        </div>
      </div>
    </>
  );
}

export default NavBar;

Now when i am trying to navigate to http://localhost:5173/about, the about component wasn't rendering. I have checked multiple online sources for a solution, but I can't find any. The same implementation was working in my other project, where that project was created using create-react-app.


Solution

  • The About component (and other routed components) doesn't render because it's not passed to the element prop correctly as a ReactNode, a.k.a. as JSX. Instead of element={About} it should be element={<About />}.

    <Routes>
      <Route path="/" element={<Home />}>
        <Route path="about" element={<About />} />
        <Route path="resume" element={<Resume />} />
        <Route path="work" element={<Work />} />
        <Route path="contact" element={<Contact />} />
      </Route>
    </Routes>
    

    Additional suggestion:

    The NavLink component applies an "active" CSS classname by default, so there's no need to use the useLocation hook and recompute the matched/active link yourself manually, the NavLink component already knows how to do this.

    function NavBar() {
      return (
        <div>
          <div className="d-flex gap-3 card-effect mt-3 ">
            <NavLink to="/about" className="icon">
              <Lucide.HomeIcon />
              <p>Home</p>
            </NavLink>
            <NavLink to="/resume" className="icon">
              <Lucide.FileTextIcon />
              <p>Resume</p>
            </NavLink>
            <NavLink to="/work" className="icon">
              <Lucide.BriefcaseIcon />
              <p>Work</p>
            </NavLink>
            <NavLink to="/contact" className="icon">
              <Lucide.ContactIcon />
              <p>Contact</p>
            </NavLink>
          </div>
        </div>
      );
    }
    
    .icon {
      // link rules here
    }
    .icon.active {
      // active link rules here
    }
    

    Edit is-this-correct-configuration-of-react-app-using-vite

    However, if you wanted to supply a different active CSS classname, then the recommended pattern is to use the classname callback syntax and access the passed isActive property.

    Example:

    <NavLink
      to="/about"
      className={({ isActive }) =>
        ["icon", isActive ? "customClassname" : ""].join(" ")
      }
    >
      <Lucide.HomeIcon />
      <p>Home</p>
    </NavLink>