22. Working with APIs and Asynchronous Data
Level: AdvancedDuration: 26m
What Is Asynchronous Data?
Most apps need to fetch data from servers or APIs—like users, posts, or products. This data is loaded asynchronously, which means it doesn’t arrive instantly. In React, we handle this safely using state and effects.
Using Fetch to Get Data
The Fetch API lets us make network requests. We typically store the data in state and use useEffect so it runs after the first render.
jsx
import { useState, useEffect } from 'react'
function Users() {
const [users, setUsers] = useState([])
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json())
.then(data => setUsers(data))
}, [])
return (
<ul>
{users.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
)
}
export default UsersUsing async/await to Simplify Fetching
jsx
useEffect(() => {
const fetchUsers = async () => {
const res = await fetch('https://jsonplaceholder.typicode.com/users')
const data = await res.json()
setUsers(data)
}
fetchUsers()
}, [])Loading and Error States
Fetching can take time, and sometimes it fails. Let’s handle loading and errors.
jsx
function Users() {
const [users, setUsers] = useState([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
const fetchUsers = async () => {
try {
const res = await fetch('https://jsonplaceholder.typicode.com/users')
if (!res.ok) throw new Error('Failed to fetch users')
const data = await res.json()
setUsers(data)
} catch (err) {
setError(err.message)
} finally {
setLoading(false)
}
}
fetchUsers()
}, [])
if (loading) return <p>Loading...</p>
if (error) return <p>Error: {error}</p>
return <ul>{users.map(user => <li key={user.id}>{user.name}</li>)}</ul>
}GET vs POST Requests
| Method | Purpose | Example |
|---|---|---|
| GET | Fetch data | Get user list |
| POST | Send data | Create a new account |
| PUT | Update data | Edit user profile |
| DELETE | Delete data | Remove a user |
Example POST request:
jsx
const createUser = async () => {
const res = await fetch('https://jsonplaceholder.typicode.com/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'New User' })
})
const data = await res.json()
console.log(data)
}Mini Project Step
Connect your app to a mock API. Replace any hardcoded project tasks with real data using the Fetch API. Add loading and error states inside your feature component.