React 4
Introduction to React-Router
In the past few weeks, you've learned how to build applications with React and the different applications and examples were all built on a single page. However, what if you wanted to have different pages with each page having its own URL (so you can bookmark it for example)? You will need to introduce a router in your application. In JavaScript, a router is the piece of code which is in charge of switching between views of your application and keep each view in sync with a specific URL. For example, you could imagine having a homepage reachable from the root path / and a users page with the path /users. In React, a popular library to help you achieve this is React-Router.
Let's look at a first example (interactive example):
const Index = () => {
return <h2>Home</h2>;
};
const About = () => {
return <h2>About</h2>;
};
const Users = ({ names }) => {
return (
<div>
<h2>Users</h2>
<ul>
{names.map(name => <li>{name}</li>)}
</ul>
</div>
);
};
const AppRouter = () => {
return (
<BrowserRouter>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about/">About</Link>
</li>
<li>
<Link to="/users/">Users</Link>
</li>
</ul>
</nav>
<Route path="/" exact component={Index} />
<Route path="/about/" component={About} />
<Route path="/users/" render={() => <Users names={["Raresh", "Nate"]} />} />
</div>
</BrowserRouter>
);
};
React-Router provides some default React components that you can use to enable routing in your application. First, notice the top level <BrowserRouter> component which wraps everything else. Each route is defined with the <Route> component which maps a path (defined with the path props) with a React component. In the simplest case, you can specify the React component to map to the path with the component props. However, it is assuming you don't need to pass any props to it. If you face a more complex scenarios or if you need to pass props to your React component, you can use the render props which takes a function and return exactly what you want to render on this path. Then, the Link component can be used to create links to navigate to different routes.
Exercise A Open the
pokedexReact application. In this exercise, React-Router will be introduced. Instead of displaying all your components in the same page, we will use React-Router to define different pages in thepokedexapplication.
- In the terminal, install React-Router with
npm install --save react-router-dom.- Open
src/App.jsand import BrowserRouter, Route and Link components from React-Router (hint:import { BrowserRouter, Route, Link } from "react-router-dom";)- Wrap all the components in the
rendermethod in the<BrowserRouter>component.- In the following, we will have
CaughtPokemonandBestPokemondisplayed with different route. But first, let's create some links to navigate to different pages. Still in therendermethod ofsrc/App.js, use theLinkcomponent to create 2 links: one to navigate to the URL/best-pokemonand another one to navigate to/caught-pokemon(hint:<Link to="/best-pokemon">Best Pokemon</Link>).- Open the
pokedexin your browser and verify that you can see 2 links on the page. When clicking on each of these links, the URL in your browser address bar should change (but nothing will change on the screen yet!).- Now let's define the routes to map a path to a React component. First, create a route to map
/best-pokemonto theBestPokemoncomponent. Then, use another route to map/caught-pokemonto theCaughtPokemoncomponent (Hint: depending on if you pass some props toBestPokemonorCaughtPokemonyou will need to use either thecomponentor therenderprops in the<Route>component).- Open the
pokedexin your browser and verify that when clicking on each link,BestPokemonandCaughtPokemonare rendered accordingly.
URL parameters
Sometimes, parameters can be passed from the URL to a React component directly via its props. In this case, different URLs can be mapped to one single React component. For example, in an online shopping application, a React component Product may be responsible to display a specific product on the page. By using URL parameters, the name or ID of the requested product can be specific in the URL and React-Router will pass it a props of the Product component (interactive example):
const Product = ({ match }) => {
return <h2>Product: {match.params.name}</h2>;
}
const AppRouter = () => {
return (
<BrowserRouter>
<div>
<nav>
<h2>Product List</h2>
<ul>
<li>
<Link to="/products/laptop">Laptop</Link>
</li>
<li>
<Link to="/products/tv">TV</Link>
</li>
<li>
<Link to="/products/teddy-bear">Teddy Bear</Link>
</li>
</ul>
</nav>
<Route path="/products/:name" component={Product} />
</div>
</BrowserRouter>
);
}
In the route definition above, a specific syntax is used to define the URL parameter: :name. Then in the Product component, the value of name can be accessed through the component props match.params.name.
Exercise B In the following, we will create a new component to display a Pokemon information. The Pokemon name will be passed through the URL and displayed on the screen.
- Create a new component
PokemonInfo.- In
src/App.js, create a new route which maps the path/pokemon/:nameto the previously created componentPokemonInfo(hint:<Route path="/pokemon/:name" component={PokemonInfo} />).- In the
rendermethod ofPokemonInfocomponent, display the name of the Pokemon which is passed in the URL parameter (hint: use the propsmatch.params.name).- Open the
pokedexin your browser and try several URLs (such ashttp://localhost:3000/pokemon/Pikachuand see if the Pokemon name is displayed accordingly on your screen.- (STRETCH GOAL) Instead of passing the name of the Pokemon in the URL parameter, now pass an ID. The ID passed correspond to the ID of the Pokemon in the Poke API. For example, the ID 1 corresponds to the Pokemon Bulbasaur (https://pokeapi.co/api/v2/pokemon-species/1/). In the
PokemonInfocomponent, use the Pokemon ID from the URL to load the corresponding Pokemon data from the Poke API and display the following Pokemon information on the screen: name, color.name, shape.name, base_happiness and capture_rate.
Further Reading
A lot of examples are available on the official React-Router website.