Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
React Hooks для работы с API: полный обзор
В современной React-разработке для работы с API используются как базовые, так и кастомные хуки, которые позволяют эффективно управлять состоянием запросов, обработкой ошибок и кэшированием данных.
Базовые хуки для API запросов
useState и useEffect — фундаментальная комбинация для выполнения запросов:
import { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
const fetchUser = async () => {
setLoading(true);
setError(null);
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) throw new Error('Network response was not ok');
const data = await response.json();
setUser(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchUser();
}, [userId]); // Зависимость от userId
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return <div>{user?.name}</div>;
}
Специализированные хуки и библиотеки
useReducer — для сложных состояний API-запросов:
const initialState = {
loading: false,
data: null,
error: null
};
function apiReducer(state, action) {
switch (action.type) {
case 'FETCH_START':
return { ...state, loading: true, error: null };
case 'FETCH_SUCCESS':
return { loading: false, data: action.payload, error: null };
case 'FETCH_ERROR':
return { loading: false, data: null, error: action.payload };
default:
return state;
}
}
React Query (TanStack Query) — профессиональное решение:
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
// useQuery для GET-запросов
function TodoList() {
const { data, isLoading, error, refetch } = useQuery({
queryKey: ['todos'],
queryFn: () => fetch('/api/todos').then(res => res.json()),
staleTime: 5000, // Данные считаются свежими 5 секунд
retry: 3, // 3 попытки при ошибке
});
}
// useMutation для POST/PUT/DELETE
function AddTodo() {
const queryClient = useQueryClient();
const mutation = useMutation({
mutationFn: (newTodo) => fetch('/api/todos', {
method: 'POST',
body: JSON.stringify(newTodo),
}),
onSuccess: () => {
queryClient.invalidateQueries(['todos']); // Инвалидация кэша
},
});
}
SWR (Stale-While-Revalidate) — альтернатива от Vercel:
import useSWR from 'swr';
const fetcher = (url) => fetch(url).then(res => res.json());
function Profile() {
const { data, error, isLoading, mutate } = useSWR(
'/api/user',
fetcher,
{
refreshInterval: 3000, // Авто-обновление каждые 3 секунды
revalidateOnFocus: true, // Ревалидация при фокусе окна
dedupingInterval: 2000, // Дедупликация запросов
}
);
// Мутация данных с оптимистичным обновлением
const updateProfile = async (updates) => {
mutate(updatedData, false); // Оптимистичное обновление
await fetch('/api/user', { method: 'PUT', body: JSON.stringify(updates) });
mutate(); // Ревалидация
};
}
Кастомные хуки для API
Универсальный хук useApi:
import { useState, useCallback } from 'react';
function useApi(apiFunction) {
const [state, setState] = useState({
data: null,
loading: false,
error: null
});
const execute = useCallback(async (...args) => {
setState(prev => ({ ...prev, loading: true, error: null }));
try {
const result = await apiFunction(...args);
setState({ data: result, loading: false, error: null });
return result;
} catch (error) {
setState({ data: null, loading: false, error: error.message });
throw error;
}
}, [apiFunction]);
return { ...state, execute };
}
// Использование
function MyComponent() {
const fetchUsers = () => fetch('/api/users').then(res => res.json());
const { data, loading, error, execute } = useApi(fetchUsers);
useEffect(() => {
execute();
}, []);
}
Преимущества специализированных решений
React Query и SWR предоставляют:
- Кэширование — избегание лишних запросов
- Фоновое обновление — обновление данных без блокировки UI
- Оптимистичные обновления — мгновенный отклик интерфейса
- Пагинация и бесконечный скролл — встроенная поддержка
- Префетчинг — предзагрузка данных
- Инвалидация кэша — автоматическое обновление связанных данных
- Дедупликация запросов — предотвращение дублирующих запросов
- Ретри с экспоненциальной задержкой — умные повторы при ошибках
Критерии выбора подхода
- Простая логика —
useState+useEffect - Сложная state-логика —
useReducer - Проект с множеством запросов — React Query (богатый функционал)
- Небольшие проекты — SWR (легковесное решение)
- Специфические требования — кастомные хуки
В современной разработке React Query стал де-факто стандартом для работы с API в React-приложениях благодаря своей комплексности, отличной документации и активному сообществу. Однако для небольших проектов или специфических случаев могут быть предпочтительнее SWR или даже кастомные решения на базе стандартных хуков.