Обработка асинхронного состояния
В мобильных приложениях часто требуется загружать данные из сети: список пользователей, постов, товаров и т.п. Такие операции асинхронны, и состояние компонента должно отражать разные этапы этого процесса: ожидание, успех или ошибку.
Типичная структура состояния
Для корректной обработки асинхронных операций рекомендуется использовать три переменные состояния:
loading— флаг загрузки,data— полученные данные,error— информация об ошибке (если произошла).
Пример инициализации:
const [loading, setLoading] = useState(true);
const [data, setData] = useState<User[] | null>(null);
const [error, setError] = useState<string | null>(null);
Пример загрузки данных
Загрузка обычно выполняется внутри эффекта (useEffect) при монтировании компонента:
import { useEffect, useState } from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
type User = {
id: number;
name: string;
};
export default function UsersScreen() {
const [loading, setLoading] = useState(true);
const [data, setData] = useState<User[] | null>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchUsers = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
if (!response.ok) throw new Error('Ошибка сети');
const users: User[] = await response.json();
setData(users);
} catch (err) {
setError(err instanceof Error ? err.message : 'Неизвестная ошибка');
} finally {
setLoading(false);
}
};
fetchUsers();
}, []);
if (loading) {
return <ActivityIndicator size="large" />;
}
if (error) {
return <Text>Ошибка: {error}</Text>;
}
return (
<View>
{data?.map(user => (
<Text key={user.id}>{user.name}</Text>
))}
</View>
);
}
Отображение состояний в интерфейсе
- Во время загрузки показывается индикатор (
ActivityIndicator). - При ошибке — сообщение об ошибке.
- При успехе — отображаются данные.
Такой подход обеспечивает предсказуемое поведение интерфейса и улучшает пользовательский опыт.
Важные замечания
- Не забывайте вызывать
setLoading(false)в блокеfinally, чтобы скрыть индикатор даже при ошибке. - Избегайте хранения только одного состояния (например,
status: 'idle' | 'loading' | 'success' | 'error') без дополнительных данных — это усложняет рендеринг. - Для повторной загрузки (например, по кнопке «Повторить») вынесите логику в отдельную функцию и вызывайте её при необходимости.