Перейти к содержимому

17. Сеть и API запросы

React Native поддерживает стандартный fetch API. Используй Axios для удобства и React Query для кеширования.

const fetchUser = async (id: number) => {
try {
const response = await fetch(`https://api.example.com/users/${id}`);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return await response.json();
} catch (error) {
console.error('Ошибка:', error);
throw error;
}
};
Окно терминала
npx expo install axios
import axios from 'axios';
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: { 'Content-Type': 'application/json' },
});
// Интерсептор для токена
api.interceptors.request.use(async (config) => {
const token = await SecureStore.getItemAsync('token');
if (token) config.headers.Authorization = `Bearer ${token}`;
return config;
});
// Запросы
const users = await api.get('/users');
await api.post('/users', { name: 'Яша' });
await api.put(`/users/${id}`, { name: 'Yasha' });
await api.delete(`/users/${id}`);
Окно терминала
npx expo install @tanstack/react-query
import { QueryClient, QueryClientProvider, useQuery, useMutation } from '@tanstack/react-query';
const queryClient = new QueryClient();
// Провайдер в App
<QueryClientProvider client={queryClient}>
<Navigation />
</QueryClientProvider>
// Запрос
function UserProfile({ userId }) {
const { data, isLoading, error, refetch } = useQuery({
queryKey: ['user', userId],
queryFn: () => api.get(`/users/${userId}`),
staleTime: 5 * 60 * 1000,
});
if (isLoading) return <ActivityIndicator />;
if (error) return <Text>Ошибка: {error.message}</Text>;
return <Text>{data.name}</Text>;
}
// Мутация
const { mutate, isPending } = useMutation({
mutationFn: (data) => api.post('/posts', data),
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['posts'] }),
});
Окно терминала
npx expo install @react-native-community/netinfo
import NetInfo from '@react-native-community/netinfo';
// Текущее состояние
const state = await NetInfo.fetch();
console.log(state.isConnected); // true/false
console.log(state.type); // 'wifi' | 'cellular' | 'none'
// Слушать изменения
const unsubscribe = NetInfo.addEventListener(state => {
if (!state.isConnected) Alert.alert('Нет интернета');
});
function useOnlineStatus() {
const [isOnline, setIsOnline] = useState(true);
useEffect(() => {
const unsub = NetInfo.addEventListener(s => setIsOnline(s.isConnected ?? true));
return unsub;
}, []);
return isOnline;
}
function OfflineBanner() {
const isOnline = useOnlineStatus();
if (isOnline) return null;
return (
<View style={styles.banner}>
<Text>📡 Нет интернета</Text>
</View>
);
}
// React Web-эквивалент React Native кода
// fetch() с loading, error и данными
import { useState } from 'react';
export default function App() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const fetchUser = async () => {
setLoading(true);
setError(null);
try {
const res = await fetch('https://jsonplaceholder.typicode.com/users/1');
if (!res.ok) throw new Error('HTTP ' + res.status);
setData(await res.json());
} catch (e) {
setError(e.message);
} finally {
setLoading(false);
}
};
return (
<div style={{ padding: 24, fontFamily: 'system-ui' }}>
<h3>Networking: fetch()</h3>
<button onClick={fetchUser} disabled={loading}
style={{ padding: '10px 20px', fontSize: 16, cursor: 'pointer' }}>
{loading ? 'Загрузка...' : 'Загрузить пользователя'}
</button>
{error && <p style={{ color: 'red' }}>Ошибка: {error}</p>}
{data && (
<div style={{ marginTop: 12, background: '#f0f0f0', padding: 12, borderRadius: 8 }}>
<p><b>{data.name}</b></p>
<p>{data.email}</p>
<p>{data.phone}</p>
</div>
)}
</div>
);
}