React Router
Last updated
Last updated
Table of Contents:
React Router - Enables navigation and routing in single-page applications (SPAs). It allows you to define routes and their corresponding components.
React Router DOM — Provides components like BrowserRouter
, Route
, and Link
to manage routing and navigation.
<BrowserRouter>
— It ensures that when users visit different URLs in your app, the right components are rendered based on those URLs.
<Route>
— Like a signpost that tells your app which page to show when you visit a certain web address.
<Link>
- Special navigation buttons that you can use to move between different pages or views in your web application.
Fallback Component — A component used to render content when no other routes match the current path.
Path Parameters - a dynamic component of a Route
path, identified using :pathParam
. For example, in the path /products/:productName
, the path parameter is :productName
and will match any URL with that pattern including /products/iPhone
, /products/foo
or even /products/5
but NOT /products/iPhone/details
useParams
- a React hook that returns an object with key:value pairs for each path parameter in the URL.
React Router is a package for handling client-side routing in a React application and lets us simulate navigation between different "pages" in our application.
What do we mean by "simulate navigation"?
Normally, when we click on a link like...
...we are redirected to a separate HTML page that our browser needs to fetch from the server.
With React Router, we can do the same kind of navigation, but we actually never leave the page. Instead of opening a separate HTML file, the same HTML file is used, but we just render different components to the screen.
😮 oooooh so smooth...
react-router-dom
React Router is not provided by default in Vite projects so we have to install it.
There is also a react-router-native
version for building mobile React apps with React Router
<BrowserRouter>
We're going to be importing a lot of things from the react-router-dom
package. The first is the BrowserRouter
component.
The BrowserRouter
component hijacks the URL bar, letting us:
render what we want to render based on the current URL (the "browser location")
use back-and-forward navigation
directly update the current browser location
<Routes>
and <Route>
sWhenever the location changes, <Routes>
looks through all its child <Route>
s to find the best matching path
and renders the provided element
.
<Link>
sThe <Link>
component will replace the <a>
tags in our HTML.
Like the <a>
tag, the <Link>
will provide a clickable button to redirect to another page.
Unlike the <a>
tag, the <Link>
will NOT actually navigate to a different file, causing a fetch. Instead, only the URL is changed, causing the <Routes>
to render a new <Route>
, but we stay on the same "page".
Suppose I had this component that I wanted to render when a URL was entered that didn't match any of the routes I defined:
This can easily be accomplished using the "*"
catch-all route. If none of the previous <Route>
had a matching path
, then this "*"
will match.
Suppose I had an array of products that I wanted to show to the user.
One solution would be to create a separate Route
and page component for each of these products:
Q: What is the issue with this approach?
In React Router, the strategy for achieving this is using path parameters.
A path parameter is a dynamic portion of a route path, indicated by a colon :
.
In the example above, we use the path parameter :productName
. The :productName
value can be replaced by anything and as a result, the Product
page component will render.
For example, what is the value of the :productName
path parameter for the following URLs?
/products/5
/products/hello
/products/banana
useParams
Okay so the Product
page component will render for /products/apple
and /products/banana
and /products/cherries
, but how does it know which product to show?
The useParams()
hook from react-router-dom
returns an object with key:value pairs that correspond to the path parameters in the current URL.
Below, you can see how we use productName
param value to find the product from the array of products.
Finally, the Products
page component should show a list of links that let me select which product I want to view.
This is often done by generating a Link
for each value in the dataset:
Q: Which of the following paths will match the /products/:id
path?
/products
/products/apple
/products/5
/products/5/about
Suppose I wanted to create a page where a user could create a new product. Let's say the path is /products/create
:
Even though the /create
portion of the last <Route>
would match the :id
, React Router is smart enough to know that the /products/create
path is hard-coded and therefore more specific than the dynamic path /products/:id
so it properly redirects us.
Currently, I'm defining all of the /products
routes by providing the full path.
We can nest <Route>
s to create sections of our application that share the same base path.
We wrap our three <Route>
s in an outer <Route>
whose path
is the base path that the child <Route>
s use.
For the first <Route>
which renders the <Products />
component, we remove the path
entirely and instead use index
which will match with the base path (/products
) provided in the parent <Route>
For each child, we can remove the /products/
part of the path