- Use React Router's
BrowserRouter
,Link
,Route
,Redirect
, andSwitch
components to add navigation to a React application - Review the React component lifecycle and use component methods to integrate with API calls
Up to this point, our React applications have been limited in size, allowing us to use basic control flow in deciding what components to render. However, as our React applications grow in size and scope, we need a more robust way of rendering different views.
We will replace standard conditional logic with the ability to render components based on changes to the url.
React Router is the most commonly-used routing library for React and we will configure it as the root component in a React application. Then we'll tell it to render other components within itself depending on the path in the url. This way we don't have to reload the entire page to swap out some data.
Here is what we are looking to build: Bitcoin Solution Code
During the introduction of useContext
we first took a look at the Provider/Consumer
model of a React app that was using React Router.
Let's take a minute once again to open the solution code and view that model again in React DevTools.
Lets take a look at the React Router Documentation first before we get started.
Note: React Router has recently been upgraded to v6 however we will be working with v5 during this lecture.
Here is our Starter Code
Let's bring in React Router and set it up to allow us to display multiple components.
First, we need to import the following dependencies:
react-router v5.2.1
react-router-dom v.5.2.1
There are several Components that will need to make use of from the React Router library.
React Router first provides us the Router
component. It talks to the browser and allows us to create history
(the ability to use the forward/back buttons) with our app, even though we are still on a single-page app. It also provides us the ability to update the URL to redirect by updating the history object.
The React Router Route
component allows us to define a URL endpoint and describe what should load on the page at that point.
We need to import the Router
into index.js
and place it as the root component of our application. Router
will,
in turn, render App
through which all the rest of our components will be rendered:
The actual Component name is called BrowserRouter
however we will take the liberty of renaming it Router
index.js
import { BrowserRouter as Router } from "react-router-dom";
And now we wrap it around the App
Component so that we can make full use or routing.
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById("root")
);
By making Router
the root component of our app, it will pass down several
router-specific objects to any components that rendered via Router
.
Things like current location and url can be accessed or changed. Additionally, in order to use the other routing components provided by React Router, a Router
parent component is necessary.
App.js
In App.js
let's import the Route
Component
A Route
has several props that tell it what route it will respond to and how it should render a component.
Here are the props available to Route
:
path
- the url that should be matchedcomponent
- the component that should be renderedrender
- jsx that is rendered directly in the route
Let's first import Route
import { Route } from "react-router-dom";
And now configure it to render the default route of Home
.
return (
<div>
<nav>
<a href="/">
<img src="https://en.bitcoin.it/w/images/en/2/29/BC_Logo_.png" alt=""/>
<h1>Bitcoin prices</h1>
</a>
<a href='/currencies'>Currencies</a>
</nav>
<main>
<Home />
<Route path="/" component={Home}/>
</main>
</div>
)
If we leave both references to Home
then React will render both of those Components. One is hard coded to render and the other is being rendered via the route defined in path
.
So let's comment out <Home />
for now.
<main>
{/* <Home /> */}
<Route path="/" component={Home}/>
</main>
Great! But this doesn't do anything because we're already on the homepage.
This does however pass down to several new props to Home
which we can see in DevTools.
Both location
and match
display info about the route.
But history
provides us with several useful methods to manipulate the route.
First let's import the Currencies
Component
import Currencies from '../Currencies/Currencies'
And now we add the route
return(
<div>
<nav>
<a href="/">
<img src="https://en.bitcoin.it/w/images/en/2/29/BC_Logo_.png" alt="" />
<h1>Bitcoin prices</h1>
</a>
<a href='/currencies'>Currencies</a>
</nav>
<main>
<Route path="/" component={Home} />
<Route path="/currencies" component={Currencies}/>
</main>
</div>
)
Now we've got two components and two route and both have be activated by clicking on the links in the nav. Two things to note however are:
- the page refreshes every time we toggle between the links
- both the Home and Currencies components are being displayed simultaneously
Let's first deal with the first issue import and use the <Link>
Component.
Let's first import Link
import { Route, Link } from "react-router-dom";
And now we replace the anchor tags with and were all set.
return (
<div>
<nav>
<Link to="/">
<img src="https://en.bitcoin.it/w/images/en/2/29/BC_Logo_.png" alt=""/>
<h1>Bitcoin prices</h1>
</Link>
<Link to="/currencies">Currency List</Link>
</nav>
<main>
<Route path="/" component={Home} />
<Route path="/currencies" component={Currencies}/>
</main>
</div>
)
Now we will resolve the second issue by including the exact keyword in the default route.
<main>
<Route exact path="/" component={Home} />
<Route path="/currencies" component={Currencies}/>
</main>
Redirects using react router are incredibly easy. Redirect is just another component we can import and use by passing it a few props.
Let's create a route to handle if/when a user manually types in a route that doesn't exist.
<main>
<Route exact path="/" component={Home} />
<Route path="/currencies" component={Currencies}/>
<Redirect to='/' />
</main>
And it looks like were done for now.
Here is the Solution Code