Dev Highlights

Доки по разработке

This project is maintained by teniryte

10. Suspense и Error Boundaries

TanStack Query v5 тесно интегрируется с React 18 Suspense и Error Boundaries, позволяя строить декларативные экраны загрузки/ошибок. Ниже собраны практики, которые обычно остаются за кадром в базовых примерах.

useSuspenseQuery

import { useSuspenseQuery } from '@tanstack/react-query';

const Article = ({ slug }: { slug: string }) => {
  const { data } = useSuspenseQuery(articleQuery(slug));
  return <ArticleBody article={data} />;
};

export const ArticlePage = ({ slug }: { slug: string }) => (
  <ErrorBoundary fallback={<ErrorState />}>
    <Suspense fallback={<ArticleSkeleton />}>
      <Article slug={slug} />
    </Suspense>
  </ErrorBoundary>
);

suspense: true в useQuery

const { data } = useQuery({
  ...profileQuery(id),
  suspense: true,
  useErrorBoundary: true,
});

Настройка Error Boundary

<QueryErrorResetBoundary>
  {({ reset }) => (
    <ErrorBoundary onReset={reset} fallbackRender={({ resetErrorBoundary }) => (
      <RetryView onRetry={resetErrorBoundary} />
    )}>
      <Suspense fallback={<Spinner />}>
        <Todos />
      </Suspense>
    </ErrorBoundary>
  )}
</QueryErrorResetBoundary>

Селекторы и Suspense

select выполняется до того, как Suspense снимет ожидание, поэтому можно безопасно маппить данные:

const { data: todoTitles } = useSuspenseQuery({
  ...todosQuery(),
  select: todos => todos.map(t => t.title),
});

Зависимые Suspense запросы

const { data: user } = useSuspenseQuery(userQuery(id));
const { data: projects } = useSuspenseQuery({
  ...projectsQuery(user.teamId),
  enabled: Boolean(user.teamId),
});

Если enabled: false, Suspense не будет ждать запрос (он просто не запустится).

Вложенные Suspense

SSR и suspense

Error recovery

Диагностика

useSuspenseInfiniteQuery

const {
  data,
  fetchNextPage,
  hasNextPage,
} = useSuspenseInfiniteQuery({
  queryKey: ['feed'],
  queryFn: ({ pageParam = 0 }) => fetchFeed(pageParam),
  getNextPageParam: lastPage => lastPage.nextCursor,
});

Фоновый refetch без “мигания”

Хелперы для маршрутизации

Мутабельные сценарии

Чеклист отладки