5.2 React Router

# What is client-side routing?

Traditional application page routing would mean loading a whole new HTML page with all of its assets (JavaScript, CSS, images, etc) from the server.

Client-side routing is controlled by your JavaScript application. It more efficiently uses AJAX to fetch any additional required assets (lazy-loading) while using JavaScript to update the DOM.

# Third party libraries

Routing is not a core component of the React UI library. There are several third-party modules that you can use with React. By far, the most popular is called react-router. It has three component libraries: react-router-dom, react-router-native, and the core react-router that is shared by both of the other two.

# Usage

The official documentation (opens new window) is quite good. There is no need to reinvent it here. The core components that you will need are:

I suggest that you start with the Primary Components Guide (opens new window).

# Demo Example

  1. Create a new React project with create-react-app
  2. Add react-router-dom to the project using yarn
yarn add react-router-dom
1
  1. Clear out the content of the default <App /> component and its CSS file.
  2. Create three stateless function components called: Home, About, and Contact
  3. Import the BrowserRouter component and make it the top / parent component in the JSX for <App />.
import { BrowserRouter as Router } from 'react-router-dom';
// ... other code ...
return (
  <Router>
    <div className="App"></div>
  </Router>
);
1
2
3
4
5
6
7
  1. Create a <nav> area at the top of the <App /> component that has links to the three other view components.
<NavLink to="/">Home</NavLink>
<NavLink to="/about">About</NavLink>
<NavLink to="/contact">Contact</NavLink>
1
2
3
  1. Below the nav-bar, add the <Route> matcher components to display the various pages / views.
<Route path="/"><Home /></Route>
<Route path="/about"><About /></Route>
<Route path="/contact"><Contact /></Route>
1
2
3
  1. Add <Switch> component as a wrapper around the <Route /> components

# Dynamic URLs

Often we need to get some route parameters from the URL.

  1. Add another route with a path of /movie/:id
  2. Add <Movie /> component
const Movie = () => {
  const { id } = useParams();
  return <h1>Movie id:{id}</h1>;
};
1
2
3
4

# Practice Exercise

Create a new React app that will fetch a list of Star Wars films from the swapi.dev API.

  • Display a list of the movie titles on the left side of the page.
  • Make them clickable links.
  • When the title of a movie is clicked, display the full movie details on the right side of the page.

# Solution

You can find the complete solution files that we reviewed in class in this GitHub repo (opens new window).

Look for the embedded comments in the code for reminders.

# Video Tutorials

# PropTypes

React has a built-in way for us to validate anything that is passed through props. Originally, PropTypes was part of the core React module. It has since been moved into its own dependency module - prop-types.

To use it we need to import it in every Component where we want to use it. Note the capitalization.

import PropTypes from 'prop-types';
1

Once imported we can define a schema to use with our component. Say that we created a component called Sidebar and it was going to be passed and array of titles to display, plus a boolean that indicates if the component should randomize the list.

Sidebar.propTypes = {
  titles: PropTypes.array.isRequired,
  random: PropTypes.bool.isRequired,
  getNewList: PropTypes.func,
};
1
2
3
4
5

Again, NOTE the capitalization of the two different PropTypes. The one that is a property of the component starts with a lowercase letter. All the prop values inside the schema object use the uppercase version that we imported.

Our object here also shows an option parameter being passed into props - getNewList. If getNewList does get passed through props then it MUST be a function.

Official reference for PropTypes (opens new window)

There are lots of different datatypes and methods in the imported PropTypes object.

PropTypes.string;
PropTypes.number;
PropTypes.bool;
PropTypes.array;
PropTypes.object;
PropTypes.element; //a component
PropTypes.symbol;
PropTypes.node; //a dom element
PropTypes.any.isRequired; //any datatype but required
PropTypes.arrayOf(PropTypes.number); //all array items are numbers
PropTypes.oneOf(['a', 'b', 'c']); //an enumeration
PropTypes.oneOfType([PropTypes.number, PropTypes.string]);
PropTypes.shape({
  id: PropTypes.number,
  name: PropTypes.string,
}); //define a schema for an object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# Resources

Last Updated: : 10/8/2021, 3:52:27 PM