Real apps get data from servers. Real apps also handle slow and failing networks.
Direct answer
Use fetch in a useEffect, store the result in state and keep separate states for loading and errors. On a device, never use localhost for your own server. Use your computer's network address or a deployed URL.
Example
import { useEffect, useState } from "react";
import { ActivityIndicator, FlatList, Text, View } from "react-native";
export default function Posts() {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
(async () => {
try {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
if (!res.ok) throw new Error("HTTP " + res.status);
setPosts(await res.json());
} catch (e) {
setError(e.message);
} finally {
setLoading(false);
}
})();
}, []);
if (loading) return <ActivityIndicator />;
if (error) return <Text>Something went wrong: {error}</Text>;
if (posts.length === 0) return <Text>No posts yet</Text>;
return (
<FlatList
data={posts}
keyExtractor={(p) => String(p.id)}
renderItem={({ item }) => <Text style={{ padding: 12 }}>{item.title}</Text>}
/>
);
}
Where Teyro fits
Teyro's React Native for Beginners course turns this into short lessons you can play in a few minutes a day. It has 80 lessons, and you can start free.
The bottom line
Loading, error, empty and success: handle all four states.


