TGViewer
Заметки про React Заметки про React @ru_react_notes · 3.43K subscribers
Post #436 2.6K
Использование Suspense с React Query

Хук useQuery в React Query возвращает опциональный объект data, он может быть или не быть, зависит от результата загрузки. Если использовать хук useSuspenseQuery, который работает с Suspense, то data будет всегда. Пример использования:


function Example() {
const { data } = useSuspenseQuery({
queryKey: ["todos"],
queryFn: fetchTodos,
});

return (
<ul>
{data.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
}

import { Suspense } from "react";
import { ErrorBoundary } from "react-error-boundary";

function Parent() {
return (
<Suspense fallback={<div>Loading...</div>}>
<ErrorBoundary fallback={<div>Something went wrong!</div>}>
<Example />
</ErrorBoundary>
</Suspense>
);
}


В примере Suspense ответственен за отображение индикатора загрузки. Если запрос закончится неуспешно, то ErrorBoundary отобразит ошибку.

В этом подходе есть ограничения. Например, если изменится queryKey, то Suspense заново отобразит индикатор загрузки. Если надо чтобы компонент Example продолжал отображаться во время повторной загрузки, то придется дополнительно использовать useTransition или useDeferredValue.

Пример с useTransition:


import { useTransition, useState } from "react";
import { useSuspenseQuery } from "@tanstack/react-query";

function Example() {
const [page, setPage] = useState(1);
const [isPending, startTransition] = useTransition();

const { data } = useSuspenseQuery({
queryKey: ["todos", page],
queryFn: () => fetchTodos({ page }),
});

function handleNextPage() {
startTransition(() => {
setPage((prev) => prev + 1);
});
}

return (
<div>
{isPending && <p>Fetching...</p>}

<ul>{/* ...render todos... */}</ul>
<button onClick={handleNextPage}>Next</button>
</div>
);
}


https://www.teemutaskula.com/blog/exploring-query-suspense
Teemutaskula Exploring using Suspense with React Query Learn how I explored using Suspense with React Query and what issues I encountered and how I solved them.
  • 👍 8
  • 👎 4
More from @ru_react_notes
  1. Jun 24, 2025Реактивность – это легко Стандартный useContext заставляет обновляться все компоненты-потр…
  2. Jun 17, 2025Остерегайтесь скрытых проблем при работе с search params Типо-безопасность — это только ве…
  3. Jun 4, 2025Почему Error Boundary, а не просто try/catch для компонентов В React нельзя использовать t…
  4. May 29, 2025Анонс TypeScript Native Вышла превью версия TypeScript написанная на Go. Ее можно установи…
  5. May 27, 2025Управление фокусом в React с помощью flushSync Установить фокус на инпуте сразу в React мо…
  6. May 15, 2025TanStack DB TanStack представила новую библиотеку – TanStack DB – реактивный клиентский ст…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →