Hydration error when using useQuery instead of useSuspenseQuery when prefetching

I have a page
export const PostsPage = async ({ params }: PostsPageProps) => {
trpc.posts.getAll.prefetch({ userId: user.id });

return (
<HydrateClient>
<PostsTable userId={user.id} />
</HydrateClient>
);
};
export const PostsPage = async ({ params }: PostsPageProps) => {
trpc.posts.getAll.prefetch({ userId: user.id });

return (
<HydrateClient>
<PostsTable userId={user.id} />
</HydrateClient>
);
};
and a component
export const PostsTable = ({ userId }: PostsTableProps) => {
const { data: posts, isPending } = trpc.posts.getAll.useQuery({
userId,
});

const { table } = useDataTable({
data: posts ?? [],
});

return (
<DataTable table={table} isLoading={isPending}>
{ /* ... */ }
</DataTable>
);
};
export const PostsTable = ({ userId }: PostsTableProps) => {
const { data: posts, isPending } = trpc.posts.getAll.useQuery({
userId,
});

const { table } = useDataTable({
data: posts ?? [],
});

return (
<DataTable table={table} isLoading={isPending}>
{ /* ... */ }
</DataTable>
);
};
Where the DataTable has some logic like
return isLoading ? (
<TableRow className="hover:bg-transparent">
{table.getLeafHeaders().map((_, i) => (
<TableCell key={i}>
<Skeleton className="h-6 w-full" />
</TableCell>
))}
</TableRow>
) : (
<TableRow>
<TableCell
colSpan={table.getAllColumns().length}
className="h-24 text-center"
>
No results.
</TableCell>
</TableRow>
)}
return isLoading ? (
<TableRow className="hover:bg-transparent">
{table.getLeafHeaders().map((_, i) => (
<TableCell key={i}>
<Skeleton className="h-6 w-full" />
</TableCell>
))}
</TableRow>
) : (
<TableRow>
<TableCell
colSpan={table.getAllColumns().length}
className="h-24 text-center"
>
No results.
</TableCell>
</TableRow>
)}
Using a useQuery in the PostsTable component results in a Hydration error. Can I prevent this without having to use Suspense? I found using the isPending flag to be a way simpler solution to rendering the skeleton in a deeply nested component.
3 Replies
Kaeon
Kaeon3w ago
I'm having the exact same question, ever found a solution for this?
Brokenwind
Brokenwind2w ago
I updated to the latest and I seem to not be getting this anymore. Can anyone confirm?
Michael Schaufelberger
Nope, not yet unfortunately. Some findings: - If I delay the SSR after prefetching significantly (e.g. sleeping right after the prefetch for 4s so the prefetch can complete), the error goes away. This basically means, that if the promise is resolved already, it works. - If I delay the query's output significantly, so the prefetch cannot be done in time, the error goes away. - Everything else, is very prone to the hydration mismatch. I.e. it happens close to 100% of the time. Upgrading to the latest for the trpc and react-query packages did not work. As of now, that is:
"@tanstack/react-query": "^5.66.11",
"@tanstack/react-query-devtools": "^5.66.11",
"@trpc/client": "11.0.0-rc.819",
"@trpc/react-query": "11.0.0-rc.819",
"@trpc/server": "11.0.0-rc.819",
"@tanstack/react-query": "^5.66.11",
"@tanstack/react-query-devtools": "^5.66.11",
"@trpc/client": "11.0.0-rc.819",
"@trpc/react-query": "11.0.0-rc.819",
"@trpc/server": "11.0.0-rc.819",
Edit: This is the case if I use query.isFetching btw. I just need to use this, because I also want to change the table's behavior in case of a refetch. But this shouldn't matter for the initial render afaik.

Did you find this page helpful?