Работа с сетью: загрузка данных через fetch
Подключаем приложение к интернету: загружаем данные с сервера и грамотно показываем загрузку и ошибки.
fetch — встроенная функция для сетевых запросов; в React Native она работает так же, как в браузере, и обычно вызывается из
useEffect.
fetch встроен
Хорошая новость: fetch в React Native доступен «из коробки», как в браузере. Никаких библиотек для базовых запросов не нужно. Он возвращает Promise, поэтому используем async/await.
async function loadUsers() {
const response = await fetch("https://api.example.com/users");
const data = await response.json();
return data;
}
Загрузка в useEffect
Данные обычно грузят при появлении экрана — то есть в useEffect с пустым массивом зависимостей. Результат кладут в состояние.
import { useState, useEffect } from "react";
import { FlatList, Text } from "react-native";
function Users() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch("https://api.example.com/users")
.then((res) => res.json())
.then((data) => setUsers(data));
}, []);
return (
<FlatList
data={users}
keyExtractor={(item) => String(item.id)}
renderItem={({ item }) => <Text>{item.name}</Text>}
/>
);
}
Три состояния экрана с данными
Любая загрузка проходит через три состояния, и каждое нужно показать пользователю:
| Состояние | Что показать |
| загрузка | индикатор (спиннер) |
| успех | данные |
| ошибка | сообщение и кнопку «повторить» |
Индикатор загрузки
ActivityIndicator — встроенный крутящийся спиннер. Его показывают, пока идёт запрос.
import { ActivityIndicator } from "react-native";
function Loading() {
return <ActivityIndicator size="large" color="tomato" />;
}
Полный пример с тремя состояниями
import { useState, useEffect } from "react";
import { View, Text, ActivityIndicator } from "react-native";
function Screen() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch("https://api.example.com/data")
.then((res) => {
if (!res.ok) throw new Error("Ошибка сервера");
return res.json();
})
.then((json) => setData(json))
.catch((e) => setError(e.message))
.finally(() => setLoading(false));
}, []);
if (loading) return <ActivityIndicator size="large" />;
if (error) return <Text>Ошибка: {error}</Text>;
return <Text>Данные загружены</Text>;
}
Обратите внимание на проверку res.ok: fetch не считает ошибкой ответ 404 или 500, поэтому статус проверяют вручную и при беде бросают исключение, которое поймает catch.
Обработка ответа — обычный JS
Логику разбора ответа можно отработать на чистом JS (запускаемый пример):
function handleResponse(status, body) {
if (status === 200) return "Данные: " + body;
if (status === 404) return "Не найдено";
return "Ошибка сервера";
}
console.log(handleResponse(200, "[users]"));
console.log(handleResponse(404, ""));
console.log(handleResponse(500, ""));
Вывод:
Данные: [users] Не найдено Ошибка сервера
Итог
fetchвстроен в RN; данные грузят вuseEffectи кладут в состояние.- Показывайте все три состояния: загрузка (
ActivityIndicator), успех, ошибка. fetchне бросает ошибку на 404/500 — проверяйтеres.okвручную.