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.
Using Fetch API to call a rest API
The global fetch()
method provides an easy way to fetch resources asynchronously across the network. The fetch() method returns a promise.
My API endpoint is https://jsonplaceholder.typicode.com/users
. This endpoint returns a user's array in the form of JSON.
{
"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
Using Axios to call a rest API
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.
npm i axios
, or yarn add axios
The usage is very similar to the fetch method.
The differences are
- Axios responses are Javascript objects. Therefore, you don't have to convert the response to a JSON object. The response is available in res.data.
.then((res: AxiosResponse) => { return res.data })
- Exceptions are caught implicitly. Manual intervention is not necessary.
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
})
}