> Как обработать ответ API в React (React)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: ITQ Group МКБ БАНК

Стек: React

> Пример ответа

Короткий ответ

Обработка ответа API в React включает три этапа: отправка запроса, парсинг ответа и обновление состояния компонента. Используется fetch или axios, async/await с try/catch, и хуки useState/useReducer для хранения данных, статуса загрузки и ошибки. Для отмены запросов при размонтировании применяется AbortController. В сложных сценариях - кастомные хуки или библиотеки вроде React Query для кэширования и ревалидации.

Подробное объяснение

Обработка ответа API в React - это не просто вызов fetch, а управление асинхронным состоянием с учётом жизненного цикла компонента. Основные элементы:

  • Асинхронный вызов: fetch или axios возвращают Promise. Используется async/await для читаемости.
  • Обработка ошибок: try/catch для сетевых ошибок и проверка response.ok для HTTP-ошибок (4xx, 5xx).
  • Управление состоянием: три состояния - loading (идёт запрос), data (успешный ответ), error (ошибка). Хранятся в useState или useReducer.
  • Побочные эффекты: запрос выполняется в useEffect с зависимостями (например, параметры запроса). Важно очищать эффект (cleanup) через AbortController, чтобы избежать обновления размонтированного компонента.
  • Кэширование и ревалидация: для повторяющихся запросов используют React Query (TanStack Query) или SWR, которые автоматически управляют кэшем, повторными попытками и синхронизацией.

Сеньор должен понимать trade-off между простым useState и библиотеками: React Query добавляет сложность, но решает проблемы stale data, race conditions и оптимистичных обновлений.

На практике

В продакшене обработка ответа API редко ограничивается одним компонентом. Типичные сценарии:

  • Кастомный хук useApi: инкапсулирует логику запроса, состояния и отмены. Переиспользуется в разных компонентах.
  • Глобальное состояние: если данные нужны в нескольких местах, используют Context + useReducer или Redux Toolkit с createAsyncThunk.
  • Интерсепторы: для axios добавляют middleware для логирования, токенов аутентификации или рефреша.
  • Обработка ошибок на уровне приложения: глобальный ErrorBoundary или перехватчик в axios для показа toast-уведомлений.
  • Race conditions: при быстром изменении зависимостей (например, поиск) старые запросы отменяются через AbortController или игнорируются с помощью флага mounted.

Пример: при загрузке списка пользователей с пагинацией используют React Query, который автоматически отменяет предыдущий запрос при смене страницы и кэширует результат.

Пример кода

JSX
import { useState, useEffect, useCallback } from 'react';
function useApi(url) {
const [state, setState] = useState({
data: null,
loading: true,
error: null,
});
const fetchData = useCallback(async (signal) => {
setState(prev => ({ ...prev, loading: true, error: null }));
try {
const response = await fetch(url, { signal });
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
setState({ data, loading: false, error: null });
} catch (err) {
if (err.name !== 'AbortError') {
setState({ data: null, loading: false, error: err.message });
}
}
}, [url]);
useEffect(() => {
const controller = new AbortController();
fetchData(controller.signal);
return () => controller.abort();
}, [fetchData]);
return state;
}
// Использование
function UserList() {
const { data, loading, error } = useApi('/api/users');
if (loading) return <div>Загрузка...</div>;
if (error) return <div>Ошибка: {error}</div>;
return <ul>{data.map(user => <li key={user.id}>{user.name}</li>)}</ul>;
}

Как отвечать на собеседовании

Начни с базового подхода (useEffect + fetch), затем покажи понимание проблем: race conditions, утечки памяти, повторные запросы. Упомяни AbortController и кастомные хуки. Для senior уровня обязательно добавь про React Query и его преимущества (кэширование, stale-while-revalidate, оптимистичные обновления). Приведи пример из реального проекта, где пришлось решать конфликт состояний или оптимизировать производительность. Избегай излишней детализации - фокус на архитектуре и trade-off.

Что проверяет интервьюер

  • Понимание асинхронности в React и жизненного цикла компонента.
  • Умение предотвращать race conditions и утечки памяти.
  • Знание современных практик (кастомные хуки, библиотеки для работы с API).
  • Способность выбирать правильный уровень абстракции (useState vs React Query).
  • Опыт обработки ошибок и краевых случаев (отмена запроса, повторные попытки).

Типичные ошибки

  • Запрос внутри компонента без useEffect - приводит к бесконечному ререндеру.
  • Игнорирование cleanup - обновление состояния после размонтирования вызывает warning и утечки.
  • Отсутствие обработки HTTP-ошибок - проверяют только catch, но не response.ok.
  • Синхронное мышление - забывают, что setState асинхронен, и пытаются использовать данные сразу после вызова.
  • Избыточное состояние - хранят loading и error в отдельных useState вместо одного объекта, что усложняет синхронизацию.
  • Неправильная работа с зависимостями useEffect - пропуск url или других параметров приводит к stale closures.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью