Lab 21: Route Parameters
Objectives
- Navigate to a route with a parameter
Steps
Navigate to a route with a parameter
- Add a - findmethod to- projectAPIto return a single- Projectby- id- src\projects\projectAPI.js- const projectAPI = {
 ...
 + find(id) {
 + return fetch(`${url}/${id}`)
 + .then(checkStatus)
 + .then(parseJSON)
 + .then(p=> new Project(p));
 + },
 +
 ...
 };
- Create the files below and add the code for these pre-built components we will use in this lab. Take a moment to review the code in them. - src\projects\ProjectDetail.jsx- import { Project } from './Project';
 export default function ProjectDetail({ project }) {
 return (
 <div className="row">
 <div className="col-sm-6">
 <div className="card large">
 <img
 className="rounded"
 src={project.imageUrl}
 alt={project.name}
 />
 <section className="section dark">
 <h3 className="strong">
 <strong>{project.name}</strong>
 </h3>
 <p>{project.description}</p>
 <p>Budget : {project.budget}</p>
 <p>Signed: {project.contractSignedOn.toLocaleDateString()}</p>
 <p>
 <mark className="active">
 {' '}
 {project.isActive ? 'active' : 'inactive'}
 </mark>
 </p>
 </section>
 </div>
 </div>
 </div>
 );
 }- src\projects\ProjectPage.jsx- import { useEffect, useState } from 'react';
 import { projectAPI } from './projectAPI';
 import ProjectDetail from './ProjectDetail';
 import { Project } from './Project';
 import { useParams } from 'react-router';
 function ProjectPage() {
 const [loading, setLoading] = useState(false);
 const [project, setProject] = useState(null);
 const [error, setError] = useState(null);
 const params = useParams();
 const id = Number(params.id);
 useEffect(() => {
 setLoading(true);
 projectAPI
 .find(id)
 .then((data) => {
 setProject(data);
 setLoading(false);
 })
 .catch((e) => {
 setError(e);
 setLoading(false);
 });
 }, [id]);
 return (
 <div>
 <>
 <h1>Project Detail</h1>
 {loading && (
 <div className="center-page">
 <span className="spinner primary"></span>
 <p>Loading...</p>
 </div>
 )}
 <div className="row">
 {error && (
 <div className="card large error">
 <section>
 <p>
 <span className="icon-alert inverse "></span> {error}
 </p>
 </section>
 </div>
 )}
 </div>
 {project && <ProjectDetail project={project} />}
 </>
 </div>
 );
 }
 export default ProjectPage;
- Add a route to display the - ProjectPage(notice that we now have a- ProjectPageand a- ProjectsPageso be careful you are in the correct file).- src\App.jsx- import ProjectsPage from './projects/ProjectsPage';
 + import ProjectPage from './projects/ProjectPage';
 function App() {
 return (
 <BrowserRouter>
 <header className="sticky">
 <span className="logo">
 <img src="/assets/logo-3.svg" alt="logo" width="49" height="99" />
 </span>
 <NavLink to="/" className="button rounded">
 <span className="icon-home"></span>
 Home
 </NavLink>
 <NavLink to="/projects/" className="button rounded">
 Projects
 </NavLink>
 </header>
 <div className="container">
 <Routes>
 <Route path="/" element={HomePage} />
 <Route path="/projects" element={ProjectsPage} />
 + <Route path="/projects/:id" element={<ProjectPage />} />
 </Routes>
 </div>
 </BrowserRouter>
 );
 }
- Make the name and description clickable by adding a - <Link />component around them.- src\projects\ProjectCard.jsx- + import { Link } from 'react-router';
 ...
 <section className="section dark">
 + <Link to={'/projects/' + project.id}>
 <h5 className="strong">
 <strong>{project.name}</strong>
 </h5>
 <p>{formatDescription(project.description)}</p>
 <p>Budget : {project.budget.toLocaleString()}</p>
 + </Link>
 <button
 type="button"
 className=" bordered"
 onClick={() => {
 handleEditClick(project);
 }}
 >
 <span className="icon-edit "></span>
 Edit
 </button>
 </section>
 ...
- Verify the new route works by the following these steps: - Visit the root of the site: http://localhost:5173/and refresh the page in your browser.
- Click on Projectsin the navigation.
- Verify you are taken to the /projectsroute and theProjectsPagedisplays.
- Click on the name or description in any of the project cards .
- Verify you are taken to the /projects/1route and theProjectPagedisplays theProjectDetailcomponent.
 - <  
- Visit the root of the site: