<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
Anchor tags refresh the page getting rid of state changes, use Link component instead. Uses to instead of href. Doesn't refresh page keeping state. Style as you would with a normal anchor tag.
Parent Route (Go to Current Route):
<NavLink to="." end> Current Directory </NavLink>
Back Button (Go back one route):
<Link to=".." relative="path" className="back-button">
<span>
Back to All Products
</span>
</Link>
Information
import { NavLink } from "react-router-dom";
<NavLink
to="/about"
className={({ isActive, isPending }) =>
isPending ? "pending" : isActive ? "active" : ""
}
>
About
</NavLink>;
Simple NavLink:
import { NavLink } from "react-router-dom";
<NavLink to="/about" className={({isActive}) => isActive ? "active" : ""}>
About
</NavLink>;
Using Style Attribute:
const activeStyle = {
color: "red"
}
<NavLink to="/about" style={({isActive}) => isActive ? activeStyle : null }>
About
</NavLink>
NavLink has a default "active" class which can be used to style active links, but also has an isActive property, a boolean, true when the route matches the link.
Info Layout Component:
export default function InfoLayout() {
return (
<>
<nav>
<NavLink to="/info" end> {/* Links to /info, can also use to="." <InfoHome /> */}
Info
</NavLink>
<NavLink to="stats"> {/* Links to /info/stats, <Stats /> */}
Statistics
</NavLink>
<NavLink to="products"> {/* Links to /info/products, <Products /> */}
Products
</NavLink>
</nav>
<Outlet />
</>
)
}
Routes Section:
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="info" element={<InfoLayout />}>
<Route index element={<InfoHome />} />
<Route path="stats" element={<Stats />} />
<Route path="products" element={<Products />} />
<Route path="products/:item" element={<ProductItem />} />
</Route>
</Route>
</Routes>
Inside Products Component:
import React from "react"
import { Link } from "react-router-dom"
export default function Products() {
return (
<>
<h1>Products</h1>
<Link to="shirts">Shirts</Link> {/* Links to /info/products/shirts */}
<Link to="shoes">Shoes</Link> {/* Links to /info/products/shoes */}
<Link to="jackets">Jackets</Link> {/* Links to /info/products/jackets */}
{/* Fetch Data and Map Links Instead If
Managing Many, Ever Changing Products Using Their Ids
Maybe make Other Components besides just Products
such as <Shirts/>, <Shoes/>, and <Jackets/>
which link to their specific items info/shirts/34
for example... */}
</>
)
}
Inside ProductItem component (/info/products/:item or /info/products/shirts):
import React, { useState, useEffect } from "react"
import { useParams, Link } from "react-router-dom"
export default function ProductItem() {
const { item } = useParams()
const [currentItem, setItem] = useState(null)
React.useEffect(() => {
fetch(`www.storename.com/info/products/${item}`)
{/* Could look something like this:
const products = {
shirts: {
imageURL: "shirtpic.jpg",
name: "Shirts",
inventory: "467",
},
shoes: {...},
jackets: {...}
}
*/}
.then(res => res.json())
.then(data => setItem(data))
}, [])
if (!currentItem) {
return <h1>Loading...</h1>
}
return (
<section>
<Link to=".." relative="path" className="back-button">
<span>
Back to All Products
</span>
</Link>
<div className="itemInfo-container">
<img src={currentItem.imageUrl} />
<h3>{currentItem.name}</h3>
<h4>Amount:{currentItem.inventory}</h4>
</div>
</section>
)
}
Links that are relative to the current URL or location. Allows to build navigation in a more flexible and portable way, when dealing with nested or dynamic URLs. Links inside routes are relative to those (parent) routes.