> Как обработать ответ 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, который автоматически отменяет предыдущий запрос при смене страницы и кэширует результат.
Пример кода
JSXimport { 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.
> Похожие задачи по frontend
Можно ли использовать useEffect в кастомном хуке
Какие хуки существуют кроме useState и useEffect
Сколько значений возвращает хук useQuery
Как работать с loading и data из useQuery
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью