T
TanStack4w ago
quickest-silver

SSR loading state

Is it possible to get SSR page and to also have loading state? I have a page with data table. Page has search params, like page, limit, sort and order. I want to achieve the behavior that: 1. If user loads page http://localhost:3000/table?page=1&limit=20&sort=name&order=asc then the page is ssr-ed to them 2. If user changes sort, order or page on the page by clicking on some button in the table header etc., I want a small spinner or something to show up while the new data is being fetched. Currently my route looks like that:
export const Route = createFileRoute(
"/{-$lang}/_layout/_main/_other/data-usage/researches/"
)({
component: RouteComponent,
validateSearch: researchesSearchParamsSchema,
loaderDeps: ({ search: { page, limit, sort, order } }) => ({
page,
limit,
sort,
order,
}),

loader: async ({ deps, context }) => {
const { data, pagination } = await context.queryClient.ensureQueryData(
getResearchesQueryOptions({ ...deps, lang: context.lang })
);

return { data, pagination };
},

errorComponent: ({ error }) => {
return <div>{error.message}</div>;
},
});
export const Route = createFileRoute(
"/{-$lang}/_layout/_main/_other/data-usage/researches/"
)({
component: RouteComponent,
validateSearch: researchesSearchParamsSchema,
loaderDeps: ({ search: { page, limit, sort, order } }) => ({
page,
limit,
sort,
order,
}),

loader: async ({ deps, context }) => {
const { data, pagination } = await context.queryClient.ensureQueryData(
getResearchesQueryOptions({ ...deps, lang: context.lang })
);

return { data, pagination };
},

errorComponent: ({ error }) => {
return <div>{error.message}</div>;
},
});
Then in the component,
const search = Route.useSearch();
const { lang } = Route.useRouteContext();
const navigate = Route.useNavigate();

const { data: researchesData } = useSuspenseQuery(
getResearchesQueryOptions({ ...search, lang })
);
// User chages the sorting by clicking title of the table that executes this:
// navigate({to: ".", search: (prev) => ({order: prev.order==="desc" ? "asc" : "desc"})
const search = Route.useSearch();
const { lang } = Route.useRouteContext();
const navigate = Route.useNavigate();

const { data: researchesData } = useSuspenseQuery(
getResearchesQueryOptions({ ...search, lang })
);
// User chages the sorting by clicking title of the table that executes this:
// navigate({to: ".", search: (prev) => ({order: prev.order==="desc" ? "asc" : "desc"})
But this results in behavior that when user clicks sort icon, nothing happens for ~0.5 second while the new data is being fetched and SSR-ed, and then, after 0.5 seconds the page changes. I still want it to be ssr-ed, for SEO purposes, but I also want loading state fire if user changes sorting, page, etc.
4 Replies
compatible-crimson
compatible-crimson4w ago
Are u adding a pending component or wrapping your useSuspenseQuery in a Suspense? should be triggered when suspense keys change https://tanstack.com/query/latest/docs/framework/react/examples/suspense
React TanStack Query Suspense Example | TanStack Query Docs
An example showing how to implement Suspense in React using TanStack Query.
ratty-blush
ratty-blush3w ago
ensureQueryData wont block if there is already stale data prefetchQuery would
quickest-silver
quickest-silverOP3w ago
I am wrappring my component with Suspense. I just didn't show it in the example Sorry could you please expand a little more on what should I do? use queryClient.prefetchQuery(...) inside the loader?
ratty-blush
ratty-blush2w ago
i think so yes

Did you find this page helpful?