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:
- BrowserRouter (opens new window)
- Switch (opens new window)
- Route (opens new window)
- NavLink (opens new window)
- useHistory (opens new window)
- useLocation (opens new window)
- useParams (opens new window)
I suggest that you start with the Primary Components Guide (opens new window).
# Demo Example
- Create a new React project with
create-react-app
- Add
react-router-dom
to the project usingyarn
yarn add react-router-dom
- Clear out the content of the default
<App />
component and its CSS file. - Create three stateless function components called: Home, About, and Contact
- 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>
);
2
3
4
5
6
7
- 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>
2
3
- 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>
2
3
- Add
<Switch>
component as a wrapper around the<Route />
components
# Dynamic URLs
Often we need to get some route parameters from the URL.
- Add another route with a path of
/movie/:id
- Add
<Movie />
component
const Movie = () => {
const { id } = useParams();
return <h1>Movie id:{id}</h1>;
};
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';
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,
};
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16