Загрузка данных из API
Настоящие приложения берут данные с сервера. В React Native доступна та же функция fetch, что и в браузере, а запрос, как и в вебе, отправляют в useEffect. На телефоне добавляются свои детали: системный индикатор загрузки и обновление списка жестом «потянуть вниз».
Список статей
Адрес https://jsonplaceholder.typicode.com/posts возвращает 100 статей с полями id, title, body. Замените локальный массив загрузкой в app/(tabs)/index.tsx:
// app/(tabs)/index.tsx
import { Link } from 'expo-router';
import { useEffect, useState } from 'react';
import { ActivityIndicator, FlatList, Text, View } from 'react-native';
import type { Post } from '@/data/posts';
const API = 'https://jsonplaceholder.typicode.com';
export default function Posts() {
const [posts, setPosts] = useState<Post[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
async function load() {
setLoading(true);
setError(null);
try {
const response = await fetch(`${API}/posts`);
if (!response.ok) throw new Error(`Ошибка ${response.status}`);
setPosts(await response.json());
} catch (err) {
setError(err instanceof Error ? err.message : 'Неизвестная ошибка');
} finally {
setLoading(false);
}
}
useEffect(() => {
load();
}, []);
if (loading && posts.length === 0) {
return <ActivityIndicator size="large" style={{ flex: 1 }} />;
}
if (error) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', gap: 12 }}>
<Text>Не удалось загрузить статьи: {error}</Text>
<Text onPress={load} style={{ color: '#2563eb' }}>Повторить</Text>
</View>
);
}
return (
<FlatList
data={posts}
keyExtractor={(item) => String(item.id)}
refreshing={loading}
onRefresh={load}
renderItem={({ item }) => (
<Link href={{ pathname: '/posts/[id]', params: { id: item.id } }} style={{ padding: 16 }}>
{item.title}
</Link>
)}
/>
);
}Сначала по центру крутится системный индикатор ActivityIndicator, затем появляется список из 100 заголовков. Тип Post по-прежнему берётся из data/posts.ts.
Обновление жестом
Пропсы refreshing и onRefresh включают у FlatList обновление жестом: потяните список вниз — появится индикатор, и load загрузит статьи заново. Пока refreshing равен true, индикатор крутится.
Ошибка и повтор
Включите режим полёта и перезапустите приложение клавишей r — вместо списка появится сообщение об ошибке. Выключите режим полёта и нажмите «Повторить»: статьи загрузятся. На телефоне связь пропадает часто, поэтому кнопка повтора нужна почти всегда.
Экран статьи
Экран app/posts/[id].tsx загружает одну статью по адресу ${API}/posts/${id} тем же способом: состояние post, loading, error и useEffect с зависимостью [id]. Комментарии к статье лежат по адресу /posts/1/comments.
Частая ошибка
Обращаться к localhost с телефона. Если вы запустили свой API на компьютере по адресу http://localhost:3000, то на телефоне localhost — это сам телефон, и запрос не дойдёт. Используйте IP-адрес компьютера в локальной сети, например http://192.168.1.10:3000. Кроме того, iOS по умолчанию блокирует запросы по http, поэтому для настоящего сервера нужен https.