> Как работать с loading и data из useQuery (React)

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

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

Стек: React

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

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

useQuery возвращает объект с полями data, loading, error и другими. loading - boolean, true пока запрос выполняется. data - результат запроса после успешного выполнения. Основная задача - корректно обрабатывать все состояния: loading, error, success. Для этого используют условный рендеринг или компонент-обёртку. В production важно также учитывать stale-данные, refetch и кэширование, которые предоставляет библиотека (например, React Query или Apollo).

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

useQuery - это хук из библиотек для работы с данными (React Query, Apollo Client, RTK Query). Он абстрагирует lifecycle запроса: инициализацию, кэширование, повторные запросы. Поля loading и data - часть этого lifecycle.

loading = true означает, что запрос ещё не завершён. Важно не путать с initial loading - если данные уже есть в кэше, loading может быть false даже при повторном запросе (stale-while-revalidate). data содержит ответ сервера, но может быть undefined при первой загрузке или null при ошибке.

Ключевые моменты:

  • loading не гарантирует отсутствие data - при использовании keepPreviousData или при optimistic updates data может быть заполнено.
  • error обрабатывается отдельно, часто через try/catch или поле error.
  • staleTime и cacheTime влияют на поведение loading: при повторных запросах в фоне loading может оставаться false, если данные считаются свежими.

На практике

В реальном коде редко используют только loading и data. Обычно добавляют:

  • Обработку ошибок (error boundary, fallback UI).
  • Показ скелетонов или спиннеров только при initial load.
  • Refetch по требованию (кнопка "обновить").
  • Оптимистичные обновления (мутации с немедленным обновлением UI).

Для loading важно различать:

  • Первичная загрузка (isLoading) - true, если нет данных в кэше.
  • Фоновая загрузка (isFetching) - true при любом запросе, даже если данные уже есть.

Пример кода

TSX
import { useQuery } from '@tanstack/react-query';
function UserProfile({ userId }: { userId: string }) {
const { data, isLoading, isFetching, error, refetch } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
staleTime: 5 * 60 * 1000, // 5 минут
});
if (isLoading) return <Skeleton />;
if (error) return <ErrorFallback error={error} onRetry={refetch} />;
return (
<div>
{isFetching && <SpinnerOverlay />}
<h1>{data.name}</h1>
<p>{data.email}</p>
<button onClick={() => refetch()}>Обновить</button>
</div>
);
}

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

Начни с определения useQuery и его роли в управлении состоянием запросов. Объясни, что loading и data - это часть объектного результата хука. Подчеркни разницу между isLoading и isFetching, если речь о React Query. Упомяни, что data может быть undefined или содержать предыдущие данные при keepPreviousData. Приведи пример обработки всех трёх состояний. Если спросят про production - добавь про staleTime, cacheTime и refetchOnWindowFocus.

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

  • Понимание lifecycle запроса и кэширования.
  • Умение различать состояния загрузки (initial vs background).
  • Знание типичных паттернов: скелетоны, error boundaries, refetch.
  • Способность объяснить trade-off между loading и isFetching.
  • Понимание, как staleTime влияет на UX.

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

  • Использование loading как единственного условия для спиннера - игнорирование isFetching при фоновых обновлениях.
  • Необработка error - пользователь видит пустой экран.
  • Предположение, что data всегда есть при loading = false - может быть undefined при ошибке.
  • Отсутствие обработки повторных запросов (refetch) - пользователь не может обновить данные.
  • Игнорирование кэширования - каждый раз показывается спиннер, даже если данные свежие.

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

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