javascriptreactjsreact-routerreact-router-domportfolio

Navigate to a page in a sub folder on item click in React JS


I'm very new to React JS but watched a few video tutorials on how to build my own portfolio. I want to map my portfolio items which contain an image, title, description, role and link. I managed to map everything except for the link to the detailed page of the respective portfolio item.

Could anyone please help me understand what I'm doing wrong and how to solve it please?

This is my folder structure:

src => pages where the main pages retain and src => pages => case-studies where the detailed pages of my portfolio items retain.

enter image description here

Here's what I got to so far:

Work.jsx in the src => pages folder

import React, { useEffect, useState } from "react";
import Loader from "./Loader";
import "./Work.css";
import WorkCard from "./WorkCard";
import WorkData from "./WorkData";

const Work = () => {
  return (
    <div className="work">
      <section className="work-section">
        <div className="card">
          <h1 className="underline">My portfolio</h1>
          <p>Here are the case studies of my projects...</p>

          <div className="grid-layout grid-2">
            {
              WorkData.map((val, index) => {
                return (
                  <WorkCard
                    key={index}
                    url={val.url}
                    image={val.image}
                    name={val.name}
                    description={val.description}
                    role={val.role} />
                 );
              })
            }
          </div>
        </div>
      </section>
    </div>
  );
}

export default Work;

WorkCard.jsx in the src => pages folder

import React from "react";
import { NavLink } from "react-router-dom";

const WorkCard = (props) => {
  return (
    <NavLink to={props.url} className="tile-card">
      <img src={props.image} alt={props.name} />
      <div className="details">
        <h2>{props.name}</h2>
        <p className="description" title={props.description}>{props.description}</p>
        <h4 className="role" title={props.role}>Role: {props.role}</h4>
      </div>
    </NavLink>
  );
}

export default WorkCard;

WorkData.jsx in the src => pages folder

import EcoPizza from "../assets/project-icons/ecoPizza.webp";
import Squared from "../assets/project-icons/Squared.webp";
import { EcoPizzaCaseStudy, SquaredCaseStudy } from "./case-studies";

const WorkData = [
  {
    "image": EcoPizza,
    "name": "The UX portfolio item name",
    "description": "This is description part",
    "role": "My role in that project",
    "url": EcoPizzaCaseStudy
  },
  {
    "image": Squared,
    "name": "The UX portfolio item name",
    "description": "This is description part",
    "role": "My role in that project",
    "url": SquaredCaseStudy
  }
];

export default WorkData;

index.js in the src => pages => case-studies folder

export { default as EcoPizzaCaseStudy } from "./eco-pizza/EcoPizzaCaseStudy";
export { default as SquaredCaseStudy } from "./squared/SquaredCaseStudy";

App.js

import React from "react";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import { Navigation } from "./components/Navigation";
import { Home, About, Work, Contact, PageNotFound, UnderConstruction } from "./pages";
import { Footer } from "./components/Footer";

function App() {
  return (
    <div className="App">
      <Router>
        <Navigation />
        <main>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/about" element={<About />} />
            <Route path="/work" element={<Work />} />
            <Route path="/under-construction" element={<UnderConstruction />} />
            <Route path="/contact" element={<Contact />} />
            <Route path='*' element={<PageNotFound />}/>
          </Routes>
        </main>
        <Footer />
      </Router>
    </div>
  );
}

export default App;

Solution

  • you are missing whole concept of routing. You can't just use item as a link to it. For that, we use Routes and then use url by Route defined accordingly.

    So you need to fill up your Routes with missing items in App.js:

    import React from "react";
    import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
    import { Navigation } from "./components/Navigation";
    import { Home, About, Work, Contact, PageNotFound, UnderConstruction } from "./pages";
    import { Footer } from "./components/Footer";
    //import required components
    import { EcoPizzaCaseStudy, SquaredCaseStudy } from "./case-studies";
    
    function App() {
      return (
        <div className="App">
          <Router>
            <Navigation />
            <main>
              <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/about" element={<About />} />
                <Route path="/work" element={<Work />} />
                <Route path="/under-construction" element={<UnderConstruction />} />
                <Route path="/contact" element={<Contact />} />
                // Add your routes
                <Route path="/eco-pizza-case-study" element={<EcoPizzaCaseStudy/>} />
                <Route path="/squared-case-study" element={<SquaredCaseStudy/>} />
                <Route path='*' element={<PageNotFound />}/>
              </Routes>
            </main>
            <Footer />
          </Router>
        </div>
      );
    }
    
    export default App;
    

    And then for url use that defined path.

    Instead "url": SquaredCaseStudy just do "url": "/squared-case-study"

    Any path you choose will work as long as it is unique. You can make it /study/squared or any other, but you need to define it in App.js to use it