Two popular ways to call a rest API from React Js are to use the Fetch API and the Axios library.
The jsonplaceholder provides fake APIs for testing and prototyping. We will be using jsonplaceholder as our API endpoint throughout this example.
The global
My API endpoint is
{
"id": number,
"name": string,
"username": string,
"email": string,
"address": {
"street": string,
"suite": string,
"city": string,
"zipcode": string,
"geo": {
"lat": string,
"lng": string
}
},
"phone": string,
"website": string,
"company": {
"name": string,
"catchPhrase": string,
"bs": string
}
}
Since I use Typescript, I need an interface to represent this user.
interface User {
id: number
name: string
username: string
email: string
address: {
street: string
suite: string
city: string
zipcode: string
geo: {
lat: string
lng: string
}
},
phone: string
website: string
company: {
name: string
catchPhrase: string
bs: string
}
}
The fetchUsers method calls the API. The fetch method returns a promise. If the promise resolves (res.ok returns true), then I convert the response to a JSON and return it. Otherwise, I will throw an exception.
.then((res) => {
if(res.ok){
return res.json()
}
throw new Error("The endpoint did not respond!")
})
If the response is successful, I set the userList to the state variable.
.then((userList) => {
setUsers(userList)
})
If I threw an exception above due to the promise failure, this is the place to catch it. You cat test this error handling by altering the API URL.
.catch((e: Error) => {
setError(e.message)
})
Here is the complete code that calls the API using the fetch method.
import { useEffect, useState } from "react"
interface User {
id: number
name: string
username: string
email: string
address: {
street: string
suite: string
city: string
zipcode: string
geo: {
lat: string
lng: string
}
},
phone: string
website: string
company: {
name: string
catchPhrase: string
bs: string
}
}
const UsersList = () =>{
const [users, setUsers] = useState<User[]>([])
const [error, setError] = useState<string>()
const fetchUsers = () => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((res) => {
if(res.ok){
return res.json()
}
throw new Error("The endpoint did not respond!")
})
.then((userList) => {
setUsers(userList)
})
.catch((e: Error) => {
setError(e.message)
})
.finally(() => {
//Any cleanup you may want to perform
})
}
useEffect(() => {
fetchUsers()
},[])
return(
<table>
<tr><td>Name</td><td>User Name</td><td>Email</td><td>Address</td></tr>
{error && <tr><td colSpan={4}>{error}</td></tr>}
{users.length > 0 && users.map((user) => {
//Ignored some fields for better clarity
return <tr>
<td>{user.name}</td>
<td>{user.username}</td>
<td>{user.email}</td>
<td>{`${user.address.street} ${user.address.city} ${user.address.zipcode}`}</td>
</tr>
})}
</table>
)
}
export default UsersList
Axios is a third-party library to communicate with REST API endpoints.
Since it is a third-party library, we must install Axios as a dependency.
The usage is very similar to the fetch method.
The differences are
Here is the code snippet to use Axios for the same API call. The rest of the code remains the same.
const fetchUsers = () => {
axios.get("https://jsonplaceholder.typicode.com/users")
.then((res: AxiosResponse) => {
return res.data
})
.then((userList) => {
setUsers(userList)
})
.catch((e: AxiosError) => {
setError(e.message)
})
.finally(() => {
//Any cleanup you may want to perform
})
}