I'm new to React and I am trying to create sub navigation that will navigate between my project pages (post pages similar to Wordpress) when the user clicks a forward or back button. I think the functionality would need to update the URL to the id I have set in my data.js
file.
Would I use a React state hook to achieve this functionality or is there a better way? I hope this makes sense and thanks in advance for any help you all can provide.
App.js file:
import { BrowserRouter, Routes, Route } from "react-router-dom";
import "./App.scss";
import About from "./pages/About";
import Error from "./pages/Error";
import Home from "./pages/Home";
import Layout from "./pages/Layout";
import Projects from "./pages/Projects";
import SingleProject from "./pages/SingleProject";
import SingleProjectLayout from "./pages/SingleProjectLayout";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
<Route path="projects" element={<SingleProjectLayout />}>
<Route index element={<Projects />} />
<Route path=":projectId" element={<SingleProject />} />
</Route>
<Route path="*" element={<Error />} />
</Route>
</Routes>
</BrowserRouter>
);
}
export default App;
data.js file:
const projects = [
{
id: "susie",
name: "Susie",
image: "https://placedog.net/800/640?id=32",
content: (
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse magnam veniam harum at qui quisquam impedit tempore reprehenderit! Ratione exercitationem reprehenderit vero! Voluptatem explicabo exercitationem alias iure eos harum non.</span>
),
projectURL: "https://placedog.net/",
},
{
id: "jimmy",
name: "Jimmy",
image: "https://placedog.net/800/640?id=100",
content: (
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse magnam veniam harum at qui quisquam impedit tempore reprehenderit! Ratione exercitationem reprehenderit vero! Voluptatem explicabo exercitationem alias iure eos harum non.</span>
),
projectURL: "https://placedog.net/",
},
{
id: "hank",
name: "Hank",
image: "https://placedog.net/800/640?id=69",
content: (
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse magnam veniam harum at qui quisquam impedit tempore reprehenderit! Ratione exercitationem reprehenderit vero! Voluptatem explicabo exercitationem alias iure eos harum non.</span>
),
projectURL: "https://placedog.net/",
},
{
id: "bosley",
name: "Bosley",
image: "https://placedog.net/800/640?id=21",
content: (
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse magnam veniam harum at qui quisquam impedit tempore reprehenderit! Ratione exercitationem reprehenderit vero! Voluptatem explicabo exercitationem alias iure eos harum non.</span>
),
projectURL: "https://placedog.net/",
},
{
id: "frank",
name: "Frank",
image: "https://placedog.net/800/640?id=22",
content: (
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse magnam veniam harum at qui quisquam impedit tempore reprehenderit! Ratione exercitationem reprehenderit vero! Voluptatem explicabo exercitationem alias iure eos harum non.</span>
),
projectURL: "https://placedog.net/",
},
{
id: "gloria",
name: "Gloria",
image: "https://placedog.net/800/640?id=24",
content: (
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse magnam veniam harum at qui quisquam impedit tempore reprehenderit! Ratione exercitationem reprehenderit vero! Voluptatem explicabo exercitationem alias iure eos harum non.</span>
),
projectURL: "https://placedog.net/",
},
{
id: "robbie",
name: "Robbie",
image: "https://placedog.net/800/640?id=60",
content: (
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse magnam veniam harum at qui quisquam impedit tempore reprehenderit! Ratione exercitationem reprehenderit vero! Voluptatem explicabo exercitationem alias iure eos harum non.</span>
),
projectURL: "https://placedog.net/",
},
{
id: "lonnie",
name: "Lonnie",
image: "https://placedog.net/800/640?id=62",
content: (
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse magnam veniam harum at qui quisquam impedit tempore reprehenderit! Ratione exercitationem reprehenderit vero! Voluptatem explicabo exercitationem alias iure eos harum non.</span>
),
projectURL: "https://placedog.net/",
},
{
id: "lady",
name: "Lady",
image: "https://placedog.net/800/640?id=54",
content: (
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse magnam veniam harum at qui quisquam impedit tempore reprehenderit! Ratione exercitationem reprehenderit vero! Voluptatem explicabo exercitationem alias iure eos harum non.</span>
),
projectURL: "https://placedog.net/",
},
];
export default projects;
SingleProjects.js
// import React, { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import projects from "../data";
import PageTitle from "../components/PageTitle";
import { LinkContainer } from "react-router-bootstrap";
import Button from "react-bootstrap/Button";
import { FaLink, FaAngleLeft } from "react-icons/fa";
import { Animated } from "react-animated-css";
function SingleProject() {
const { projectId } = useParams();
const project = projects.find((project) => project.id === projectId);
const { image, name, content, projectURL } = project;
return (
<>
<PageTitle title={name} />
<section className="container my-5">
<div className="row">
<div className="col-12 col-lg-8">
<Animated
animationIn="fadeIn"
animationOut="fadeOut"
animationInDuration={1000}
isVisible={true}
>
<img className="img-fluid vw-100" src={image} alt={name} />
</Animated>
</div>
<div className="col-12 col-lg-4">
<Animated
animationIn="fadeIn"
animationOut="fadeOut"
animationInDuration={1000}
isVisible={true}
>
<div className="mt-3 mt-lg-0">
<h2>Project Info:</h2>
<p>{content}</p>
<hr></hr>
<div className="d-flex justify-content-between mb-5">
<span className="d-flex align-items-center">
<FaLink />
<span className="text-bold ps-2">URL:</span>
</span>
<a href={projectURL} rel="noreferrer" target="_blank">
{projectURL}
</a>
</div>
<LinkContainer to="/projects">
<div className="text-left">
<Button
variant="primary"
className="d-flex align-items-center"
size="lg"
>
<FaAngleLeft className="me-2" />
Back to Projects
</Button>
</div>
</LinkContainer>
{/* I would like this button to navigate to the next project's id pulled from my data.js array. */}
<Button variant="primary" size="lg">
Next
</Button>
</div>
</Animated>
</div>
</div>
</section>
</>
);
}
export default SingleProject;
CodePudding user response:
- Find the index of current project. You can use
for
loop,findIndex
, etc. projects[currentIndex 1]
will be your next project. Check thatcurrentIndex 1
is not greater than the projects last index.
// Inside your render function. For instance below the line you declare `project`.
const currentProjectIndex = projects.findIndex(project => project.id === projectId)
const nextProject = projects[currentProjectIndex 1]
You have 2 options to navigate:
useNavigate
There is a useNavigate hook which you can import from react-router
. It returns a function which lets you to navigate to a different URL.
const navigate = useNavigate();
Call
navigate(`/projects/${nextProject.id}`)
inside onClick
event handler of the button you want. Make sure that nextProject
exists before you call the navigate
function.
Link
You can import the Link component from react-router-dom'
and render it instead of button
component.
<Link to={`/projects/${nextProject.id}`}> Next</Link>