React JS: Lab#RE02-1
Introduction
React Router enables “client side routing”.
Client side routing allows your app to update the URL from a link click without making another request for another document from the server.
Main concepts of Router
Getting started
Install dependencies
- Router:
Create the project directory structure
Project structure
src
├── App.css
├── App.js
├── App.test.js
├── components // Here we'll create each of the Hook examples
│ └── PersonCard
│ └── index.jsx
├── index.css
├── index.js
├── logo.svg
├── pages
│ ├── contact
│ │ └── Contact.jsx
│ ├── home
│ │ └── Home.jsx
│ └── people
├── reportWebVitals.js
├── route
│ ├── Footer.jsx
│ ├── Layout.jsx
│ └── NoPage.jsx
└── setupTests.js
Adding components
Hooks
API Rest
We’ll use the public API JSONPlaceHolder to access data through an API. We’ll use axios
to send HTTP requests to the API.
setData
function as the useEffect
dependency?
Install required packages
axios
is a promise-based HTTP client for node.js and the browser.
- It is
isomorphic
, meaning…- On the server-side it uses the native
node.js
HTTP module - On the client (browser) it uses
XMLHttpRequests
- On the server-side it uses the native
We use the Axios library to fetch data from the JSONPlaceholder API, which provides a fake REST API for testing and prototyping.
Install axios
using npm
:
Create the component
Let’s create a new component:
- It’s project path will be:
src/components/AxiosApiRest/index.jsx
Let’s start by initializing a state variable called data
that will store the response received from the API:
A useState
manages its state and sets data
initial value to an empty array.
Let’s also set the API url as a constant:
Now we’ll create a useEffect
to fetch the data from the API and upate the data
state variable when:
- The component is mounted (on initialization time)
- The
setData
function is called
useEffect(() => {
// Configure the axios command to retrieve data from the API
axios
.get(url)
// 'then' is executed only if data has been received from the GET request
.then((response) => {
// Assign the received data to the 'data' state variable -> This will trigger again the useEffect hook
setData(response.data);
})
// If there's some kind of error on the GET request, catch it and print it as a console log
.catch((error) => {
console.log(error)
});
}, [setData]); // Set 'setData' as a dependency of the useEffect to trigger it
This should act as a kind-of-recursive function, as the useEffect
triggers itself again if a response is received from the GET request to the API.
Finally, return the HTML rendered component:
return (
<>
<h1>My data todos from axios</h1>
{ /* Only render this part if data is not empty */}
{ data &&
data.map((item) => {
return(
<spam key={item.id}>
id: {item.id}
<spam>userId: {item.userId}</spam>
<spam>title: {item.title}</spam>
<spam>completed: {item.completed}</spam>
<br />
</spam>
);
})
}
</>
);
The final component should be something like this:
AxiosApiRest/index.jsx
import React, { useEffect, useState } from 'react';
import axios from 'axios';
export default function AxiosApiRest() {
// Declare the 'data' state variable
const [data, setData] = useState([]);
// Define the REST API URL to request data from
const url = "https://jsonplaceholder.typicode.com/todos";
// Define the 'useEffect' that will fetch the data
useEffect(() => {
// Configure the axios command to retrieve data from the API
axios
.get(url)
// 'then' is executed only if data has been received from the GET request
.then((response) => {
// Assign the received data to the 'data' state variable -> This will trigger again the useEffect hook
setData(response.data);
})
// If there's some kind of error on the GET request, catch it and print it as a console log
.catch((error) => {
console.log(error)
});
}, [setData]); // Set 'setData' as a dependency of the useEffect to trigger it
// Return the rendered component
return (
<>
<h2>My data todos from axios</h2>
{ /* Only render this part if data is not empty */}
{ data &&
data.map((item) => {
return(
<spam key={item.id}>
id: {item.id}
<spam>userId: {item.userId}</spam>
<spam>title: {item.title}</spam>
<spam>completed: {item.completed}</spam>
<br />
</spam>
);
})
}
</>
);
}
Add a new page in src/pages/apirest/ApiRest.jsx
pointing towards the component and the corresponding route to that page in the App.js
:
src/pages/apirest/ApiRest.jsx
src/App.js
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Layout from "./route/Layout.jsx";
import Home from "./pages/home/Home.jsx";
import HooksExamples from "./pages/hooksexamples/HooksExamples.jsx"
import Contact from "./pages/contact/Contact.jsx";
import NoPage from "./route/NoPage.jsx";
import ApiRest from "./pages/apirest/ApiRest.jsx";
function App() {
// View with return JSX
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="hooksexamples" element={<HooksExamples />} />
<Route path="apirest" element={<ApiRest />} />
<Route path="contact" element={<Contact />} />
<Route path="*" element={<NoPage />} />
</Route>
</Routes>
</BrowserRouter>
);
}
export default App;