← Назад к вопросам

Какие знаешь hooks для работы с API?

1.0 Junior🔥 171 комментариев
#React

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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 или даже кастомные решения на базе стандартных хуков.

Какие знаешь hooks для работы с API? | PrepBro