import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Home from './pages/Home'
import About from './pages/About'
import Products from './pages/Products'
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="products" element={<Products />} />
</Routes>
</BrowserRouter>
)
}
export default App
Link
If we want to navigate through our app internally, then we use Link. Link is similar to <a href but is used to open different page in our app and not external URLs like google.com
Let's say I am in Home page, / and I want to navigate to About page, /about then we can either type the /about in URL or use Link (when clicked will take us to /about page).
import { Link } from 'react-router-dom'
const Home = () => {
return (
<section className="section">
<h2>Home Page</h2>
<Link to="/about" className="btn">
About
</Link>
</section>
)
}
export default Home
If we need to go to external URLs like google.com, then we still need to use <a href
Error Page
If we navigate to non-existing URL within our app then it shows a blank page by default which is not a good user experience. We can define a wildcard route (*) which goes to the page we say if none of the above routes match
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Home from './pages/Home'
import About from './pages/About'
import Error from './pages/Error'
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
// DEFAULT ROUTE IF ABOVE ROUTES DON'T MATCH
<Route path="*" element={<Error />} />
</Routes>
</BrowserRouter>
)
}
export default App
import { Link } from 'react-router-dom'
const Error = () => {
return (
<section className="section">
<h1>404</h1>
<h2>Page not found</h2>
<Link to="/" className="btn">
Back Home
</Link>
</section>
)
}
export default Error
Navbar
We want a navbar/ footer that will be common to all the pages (Home, about, and products). We can achieve it by
nesting these routes inside common path. For example, we want all routes to start at /
/
/about
/products
Once we nest them, we also need to use outlet section inside main route / so that this <Outlet/> will be either Home, Or About or Products
We need to know which link is selected, so we often add an active class. We can make use of NavLink provided by react-router-dom instead of Link. The difference is, the NavLink will show us if selected link is active or not.
Let's say we have products page that contains a list of products, and when we click on a product it will take us to details of individual product. We can make use of useParam() hook to see dynamically what ID is passed
App.js
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<SharedLayout />}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
// These two routes below (products and it's id route can also be nested. Will see later how)
<Route path="products" element={<Products />} />
// this id will be passed as a parameter in url and we can know that id using useParam hook
<Route path="products/:productId" element={<SingleProduct />} />
<Route path="*" element={<Error />} />
</Route>
</Routes>
</BrowserRouter>
)
}
import { Link, useParams } from 'react-router-dom'
import products from '../data'
const SingleProduct = () => {
// we get the dynamically passed parameter using useParams()
const { productId } = useParams()
return (
<section className="section product">
<h2>{productId}</h2>
<Link to="/products">back to products</Link>
</section>
)
}
export default SingleProduct
Navigate (useNavigate)
Let's say we have a /login route that displays a login form, and when user logs in by filling creds, it should navigate us to Dashboard page. In Dashboard page, if user entered the creds, it should show "Hello, name", else it should display "Hello"
App.js
function App() {
const [user, setUser] = useState(null)
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<SharedLayout />}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
// products and products/:productId could be nested (we will see how to do this later)
<Route path="products" element={<Products />} />
<Route path="products/:productId" element={<SingleProduct />} />
<Route path="login" element={<Login setUser={setUser} />} />
<Route path="dashboard" element={<Dashboard user={user} />} />
<Route path="*" element={<Error />} />
</Route>
</Routes>
</BrowserRouter>
)
}