Доки по разработке
This project is maintained by teniryte
TanStack Query глубоко интегрирован с React Suspense. Это особенно полезно в React 18+, App Router и потоковом SSR.
useSuspenseQueryimport { useSuspenseQuery } from '@tanstack/react-query'
function Article({ slug }: { slug: string }) {
const query = useSuspenseQuery(articleOptions(slug))
return <ArticleView article={query.data} />
}
Особенности:
data гарантированно определёнSuspenseErrorBoundary<ErrorBoundary fallback={<ErrorState />}>
<Suspense fallback={<ArticleSkeleton />}>
<Article slug={slug} />
</Suspense>
</ErrorBoundary>
Это делает код компонента чище: внутри него не нужно вручную разруливать isPending и isError.
QueryErrorResetBoundaryЧтобы retry после ошибки работал предсказуемо:
import { QueryErrorResetBoundary } from '@tanstack/react-query'
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<button onClick={resetErrorBoundary}>Try again</button>
)}
>
<Suspense fallback={<Spinner />}>
<TodosScreen />
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
useSuspenseQueriesconst [user, projects] = useSuspenseQueries({
queries: [userOptions(userId), projectsOptions(teamId)],
})
Помните про ограничения актуального API:
enabledplaceholderDatathrowOnErroruseSuspenseInfiniteQueryconst feed = useSuspenseInfiniteQuery({
queryKey: ['feed'],
initialPageParam: null,
queryFn: ({ pageParam }) => fetchFeed(pageParam),
getNextPageParam: (lastPage) => lastPage.nextCursor,
})
Suspense ждёт первую загрузку. Следующие страницы вы уже контролируете через fetchNextPage.
if (isPending)useQuery прощеenabledСогласно текущей документации, cancellation не работает для:
useSuspenseQueryuseSuspenseQueriesuseSuspenseInfiniteQueryЕсли отмена критична, оставайтесь на обычных query hooks.
Самый приятный UX обычно получается так:
SuspenseuseSuspenseQueryТогда Suspense fallback либо не показывается вовсе, либо показывается минимально.
Хорошая практика:
ErrorBoundary на уровне страницыТак одна ошибка не уронит весь экран.