React does not have a built-in router, but we can easily install it with the react-router-dom
library. Routing is the way the web redirects.
For example, if you visit taniarascia.com , you will go to taniarascia.com homepage. If you go to taniarascia.com/me , you will be redirected to the “about me” page. If you visit taniarascia.com/categories/javascript or taniarascia.com/categories/css , you will go to the category list page. The route will be as follows:
1 2 3 4 | / - root /:page_id - page /categories/:category_id - category |
This website is also an SPA, only 1 page will load and every click to the new page will load some additional JSON data, but not really request resources from index.html and about-me.html. I will show you how to install a simple SPA with React with react-router-dom, and pull data via URLs. You can see the source code here :
Before reading this article, you should read:
- Getting Started with React or Build a React App with Hooks if you are new to React or React hooks
- How to Connect to an API in JavaScript if you don’t already know how to work with the API.
Setting
Create a new React app
1 2 | npx create-react-app router-example |
The project has 2 attachments, react-router-dom
for the router and axios
for API calls:
1 2 | npm install react-router-dom axios |
Or
1 2 | yarn add react-router-dom axios |
BrowserRouter
To use react-router-dom
, we need to wrap the entire App component in BrowserRouter. There are 2 types of routers:
- BrowserRouter – create beautiful standard URLs like example.com/about
- HashRouter – create URL with hashtag like example.com/#about
Let’s use BrowserRouter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // src/index.js import React from 'react' import { render } from 'react-dom' import { BrowserRouter } from 'react-router-dom' import App from './App' render( <BrowserRouter> <App /> </BrowserRouter>, document.querySelector('#root') ) |
Router and Switch
In the App.js file, we can decide which routes we want to use and navigate accordingly. We will use Route and Switch for this section.
- switch – group all routes together, and make sure they are prioritized from top to bottom.
- route – each route individually
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // App.js import React from 'react' import { Route, Switch } from 'react-router-dom' // We will create these two pages in a moment import HomePage from './pages/HomePage' import UserPage from './pages/UserPage' export default function App() { return ( <Switch> <Route exact path="/" component={HomePage} /> <Route path="/:id" component={UserPage} /> </Switch> ) } |
We are leaving the root (/)
as HomePage, and automatically matching other pages with UserPage. I only have 1 route for this simple example, but you can do more:
1 2 3 4 5 6 7 | <Switch> <Route exact path="/" component={HomePage} /> <Route path="/:id" component={UserPage} /> <Route path="/categories" component={CategoriesPage} /> <Route path="/categories/:id" component={IndividualCategoryPage} /> </Switch> |
This ensures that taniarascia.com/categories will lead to a list of category pages , but taniarascia.com/categories/javascript will lead to a completely different template for category listings.
Link
To link to another SPA page, we use the Link tag. If we use the <a href="/route">
tag, it will create a new request and reload the page, and Link
helps us to do this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //src/pages/HomePage.js import React, { Component } from 'react' import { Link } from 'react-router-dom' export default function HomePage() { return ( <div className="container"> <h1>Home Page</h1> <p> <Link to="/taniarascia">taniarascia</Link> on GitHub. </p> </div> ) } |
Now go to the first route, root is loaded in HomePage, and see the following content as shown below.
Dynamic Route Parameter
Link to navigate to / taniarasca, where will match with /: id in Route. To be flexible in getting the content from the URL – in this case, taniarasca – we will use match.params.id
from the props.
I will use param to make a call to the Github API and get data. In this example, I will use Hooks, so if you are not familiar with them, you can read the article Building a CRUD App with Hooks .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | src/pages/UserPage.js import React, { useState, useEffect } from 'react' import axios from 'axios' export default function UserPage(props) { // Setting initial state const initialUserState = { user: {}, loading: true, } // Getter and setter for user state const [user, setUser] = useState(initialUserState) // Using useEffect to retrieve data from an API (similar to componentDidMount in a class) useEffect(() => { const getUser = async () => { // Pass our param (:id) to the API call const { data } = await axios(`https://api.github.com/users/${props.match.params.id}`) // Update state setUser(data) } // Invoke the async function getUser() }, []) // Don't forget the `[]`, which will prevent useEffect from running in an infinite loop // Return a table with some data from the API. return user.loading ? ( <div>Loading...</div> ) : ( <div className="container"> <h1>{props.match.params.id}</h1> <table> <thead> <tr> <th>Name</th> <th>Location</th> <th>Website</th> <th>Followers</th> </tr> </thead> <tbody> <tr> <td>{user.name}</td> <td>{user.location}</td> <td> <a href={user.blog}>{user.blog}</a> </td> <td>{user.followers}</td> </tr> </tbody> </table> </div> ) } |
Conclude
If you missed something in the post, you can view the source here