API Integration in React
As a beginner, you might wonder: "Where does the data on websites come from?" It usually comes from an API (Application Programming Interface).
Think of an API like a waiter in a restaurant:
- You (The React App) are the customer.
- The API (The Waiter) takes your request.
- The Server (The Kitchen) prepares the data.
- The API brings the data back to your table.
1. The "Fetch" Cycle
In React, fetching data usually happens in three stages. We use State to keep track of these stages so the user knows what's happening.
- Loading State: "Wait, I'm getting the data..." (Show a spinner).
- Success State: "I got it! Here it is." (Show the data).
- Error State: "Oops, something went wrong." (Show an error message).
import { useState, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState(null); // Where we store the data
const [isLoading, setIsLoading] = useState(true); // To show a loading message
const [error, setError] = useState(null); // To show an error message
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(json => {
setData(json);
setIsLoading(false);
})
.catch(err => {
setError(err.message);
setIsLoading(false);
});
}, []);
if (isLoading) return <p>Fetching data from the server...</p>;
if (error) return <p>Error: {error}</p>;
return (
<div>
<h1>Fetched Data:</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
}
2. Using the fetch() API
Modern browsers have a built-in function called fetch(). Since fetching data is a "Side Effect" (it happens outside of React's rendering), we always put it inside a useEffect hook.
The Noob-Friendly Pattern:
import { useState, useEffect } from 'react';
function UserList() {
const [users, setUsers] = useState([]); // Where we store the data
const [isLoading, setIsLoading] = useState(true); // To show a loading message
useEffect(() => {
// 1. Call the API
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.json()) // 2. Turn response into JSON
.then((data) => {
setUsers(data); // 3. Save data to state
setIsLoading(false); // 4. Turn off loading
})
.catch((error) => console.error("Error fetching data:", error));
}, []); // [] means: "Only do this once when the page loads"
if (isLoading) return <p>Fetching users from the server...</p>;
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
3. Async/Await (The Cleaner Way)
The .then() syntax can get messy. Professional developers prefer Async/Await because it reads like normal English.
import { useState, useEffect } from 'react';
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const result = await response.json();
setData(result);
} catch (error) {
console.log("Something broke:", error);
}
};
4. Common API Rules for Beginners
- The Dependency Array: Always use an empty array
[]inuseEffectfor data fetching. If you forget it, your app will fetch data in an infinite loop, which can crash the server (or your browser!). - Unique Keys: When you display a list of data using
.map(), always give the top element akey={item.id}. It helps React stay fast. - JSON is your friend: Almost all APIs send data in JSON format. It looks just like a JavaScript object.
{
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com"
}
Practice: The Random Joke Generator
Let's build something fun! We will use a free API to get a random joke.
import { useState } from 'react';
function JokeApp() {
const [joke, setJoke] = useState("Click the button to get a joke!");
const getJoke = async () => {
setJoke("🤔 Thinking...");
const response = await fetch("https://official-joke-api.appspot.com/random_joke");
const data = await response.json();
setJoke(`${data.setup} ... ${data.punchline}`);
};
return (
<div className="card">
<h3>Project: Joke Generator</h3>
<p>{joke}</p>
<button onClick={getJoke}>Get New Joke</button>
</div>
);
}
Don't have a backend yet? Use these "Placeholder" APIs to practice:
- JSONPlaceholder: Great for fake users, posts, and comments.
- PokeAPI: Great for learning how to handle complex data (Pokemon!).
- OpenWeather: Great for learning how to use API Keys.
When your page first loads, your state might be null. If you try to access data.name before the API finishes, your app will crash. Always use Conditional Rendering (like data && data.name) to stay safe!