T
TanStack9mo ago
correct-apricot

Using useSuspenseQuery for paginated requests

Am I understanding correctly that useSuspenseQuery is not the preferred way to render paginated data because, when changing pages, it is harder to show a loading state due to the existing data from the previous page? Or am I missing something? I am changing pages through React Router search params from another component. Currently, page changes work, but there is no indication of a loading state as there is with the initial useSuspenseQuery fetching.
10 Replies
adverse-sapphire
adverse-sapphire9mo ago
status is always success the derived flags are set accordingly.
so these do not make sense to use:
isPending: boolean A derived boolean from the status variable above, provided for convenience. isSuccess: boolean A derived boolean from the status variable above, provided for convenience. isError: boolean A derived boolean from the status variable above, provided for convenience.
Can you try using isFetching to show the loading indicator?
correct-apricot
correct-apricotOP9mo ago
The problem with isFetching is that it also triggers the loading indicator when the page is being refetched (e.g., when you focus on the tab again). This makes it difficult to know whether you're refetching the same page or navigating to a different one.
passive-yellow
passive-yellow9mo ago
We use a modified version of this hook: https://www.teemutaskula.com/blog/exploring-query-suspense It will suspend to your suspense boundary on first load but not subsequent loads. This allows us to show a small spinner that is localized to the change when we want but otherwise only show the initial suspense boundary fallback state initially.
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.
correct-apricot
correct-apricotOP9mo ago
Woah, that looks exactly like what I've been looking for. Thanks!
correct-apricot
correct-apricot9mo ago
careful with this tho: return { ...query, isSuspending }; https://tanstack.com/query/latest/docs/framework/react/guides/render-optimizations#tracked-properties
If you use object rest destructuring, you will disable this optimization.
const newQuery = query as typeof query & { isSuspending: boolean };
newQuery.isSuspending = query.isFetching && queryKey !== deferredQueryKey;

return newQuery;
const newQuery = query as typeof query & { isSuspending: boolean };
newQuery.isSuspending = query.isFetching && queryKey !== deferredQueryKey;

return newQuery;
I use this instead
correct-apricot
correct-apricotOP9mo ago
You saved me a lot of time debugging, I think. Thank you!
absent-sapphire
absent-sapphire9mo ago
Hi everyone 👋 Happy to hear that my article was helpful and thanks for pointing out the issue with property tracking. I've updated the article to use the proposed solution by @ferretwithabéret If you guys have any other improvement ideas don't hesitate to share 😊
correct-apricot
correct-apricot9mo ago
Ngl, I was thinking about emailing you about it, glad you noticed this thread
absent-sapphire
absent-sapphire9mo ago
@514sid actually emailed me about it which is how I noticed this discussion 😄 So big thanks to Sid as well 🤝
correct-apricot
correct-apricot5mo ago
This seems to trigger react-compiler's eslint rules, at least in my RN project. Fixed it with
const newQuery = query as typeof query & { isSuspending: boolean };
Object.assign(newQuery, {
isSuspending: query.isFetching && queryKey !== deferredQueryKey,
});
const newQuery = query as typeof query & { isSuspending: boolean };
Object.assign(newQuery, {
isSuspending: query.isFetching && queryKey !== deferredQueryKey,
});

Did you find this page helpful?