Loading Data from an API
Use fetch inside useEffect to load data when a screen opens, then show it in a list.
What you will learn
- Fetch data with fetch and async/await
- Run it once on load with useEffect
- Show a loading state, then the data
Same fetch, same useEffect
Most apps show data that lives on a server somewhere — a list of users, products or posts. To get it, your app talks to an API (Application Programming Interface — a way for one program to ask another program for data over the internet). The reply usually comes back as JSON (JavaScript Object Notation — a simple text format for objects and lists that looks just like JavaScript).
Loading data works just like web React: call fetch (the built-in function that sends a request to a URL) to get that JSON, and run it inside useEffect so it happens once when the screen opens. You keep the result and a loading flag in state.
Think of it as a three-step relay: ask the server (fetch), wait for the reply, then show what came back. While you wait you display a spinner so the screen never looks frozen or blank.
What the data looks like
Before the code, it helps to know the shape of what the server sends back. The free test API jsonplaceholder.typicode.com/users returns an array of user objects like this:
[
{ "id": 1, "name": "Leanne Graham", "email": "leanne@april.biz" },
{ "id": 2, "name": "Ervin Howell", "email": "ervin@melissa.tv" }
]Note: Output:
(This is sample data, not program output.) Each object has an id, a name and an email. That is why, in the next code, item.name shows the person’s name — it reads the name field from one of these objects.
Load and show users
Here we fetch those users, show a spinner while waiting, then list the names:
import { useState, useEffect } from 'react';
import { FlatList, Text, ActivityIndicator, View } from 'react-native';
export default function App() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then((res) => res.json())
.then((data) => {
setUsers(data);
setLoading(false);
});
}, []); // [] = run once when the screen opens
if (loading) return <ActivityIndicator size="large" />;
return (
<FlatList
data={users}
keyExtractor={(u) => String(u.id)}
renderItem={({ item }) => <Text style={{ padding: 12 }}>{item.name}</Text>}
/>
);
}Note: Output:
A spinner appears for a moment, then a scrollable list of names like:
Leanne Graham
Ervin Howell
Clementine Bauch
...
The empty array [] at the end of useEffect means "run once". Without it, the fetch could loop forever.
The whole request–response flow, step by step
A request is your app asking the server for data; the response is what the server sends back. (HTTP — HyperText Transfer Protocol — is just the agreed language phones and servers use to make that request and reply.) Here is the full trip our code takes, in order:
- The screen first draws with
usersempty andloadingset totrue, so theif (loading)line shows the spinner (ActivityIndicator). - When the screen opens,
useEffectruns once (because of the[]) and callsfetch('https://jsonplaceholder.typicode.com/users')— the request goes out over the internet. - Your app waits. The spinner keeps spinning so the screen never looks frozen.
- The server replies with the text of the JSON list.
.then((res) => res.json())turns that raw text into a real JavaScript array of objects. - The next
.then((data) => ...)receives that array.setUsers(data)stores the users in state andsetLoading(false)turns the spinner off. - Those two state changes re-render the component. Now
loadingisfalse, so theifis skipped and theFlatListruns instead. - The
FlatListdraws oneTextper user, showingitem.name— the names you see on screen.
Watch out: Never forget the dependency array. useEffect(fn) with no array runs after every render, so a fetch that sets state would trigger another render and fetch again — an endless loop. Use useEffect(fn, []) to run once.
Tip: Real networks fail sometimes. Wrap the fetch in try/catch (or add a .catch) and keep an error state so you can show a friendly "Could not load" message instead of a blank screen.
Q. What does the empty array [] at the end of useEffect do?
✍️ Practice
- Change the URL to
/postsand show each post’stitle. - Add a
.catchthat logs an error and anerrorstate with a fallback message.
🏠 Homework
- Fetch a list from any free public API and display three fields from each item in a
FlatList.