query
query copied to clipboard
Bug: Dependent Query doesn't work with solid-js SSR
Describe the bug
In the Tanstack documentation there is a section about dependent queries: https://tanstack.com/query/latest/docs/framework/react/guides/dependent-queries
The example suggest that you should use enable to create dependent queries. The problem when using enable is that when it is disabled it doesn't suspend the current context and therefore doesn't fetch on the server.
Your minimal, reproducible example
https://codesandbox.io/p/github/BierDav/temp-tanstack-query-ssr-bug/master?import=true
Steps to reproduce
- Open codesandbox
- Run ´pnpm dev`
- Open the preview
- Now the server waits for 2 seconds before responding because of the
timoutquery insrc/routs/index.tsx, but the moment it finishes it doesn't care about the second query getting enabed and returning it immediately to the browser. - This causes that the client has to fetch the remaining
statequery. You can see that in the dev tools:
Expected behavior
The expected behavior would be that both queries are beeing evaluated before the server sends its initial response. But I don't know if this is even possible with this syntax from a technical perspective.
How often does this bug happen?
Every time
Screenshots or Videos
import { createQuery } from "@tanstack/solid-query";
export default function () {
const timeout = createQuery(() => ({
queryKey: ["timeout"],
queryFn: () =>
new Promise((resolve) => setTimeout(() => resolve("test"), 2000)),
}));
const state = createQuery(() => ({
queryKey: ["realQuery"],
queryFn: async () => {
const resp = await fetch("https://api.sampleapis.com/switch/games");
console.log("fetched");
return await resp.json();
},
enabled: !!timeout.data,
}));
return <>{JSON.stringify(state.data?.[0])}</>;
}
Platform
- Windows
- Node v21.7.3
- Chrome
Tanstack Query adapter
solid-query
TanStack Query version
v5.40.0
TypeScript version
No response
Additional context
No response
@ardeora FYI
I'm not sure about solid but in react, suspense runs in serial per component, which is why enabled makes no sense. So enabled: !!timeout.data, is not necessary because timeout.data would always be defined. useSuspenseQuery also has this built-in on type level, but again, I don't know enough how solid works in this regard.
@TkDodo to make it clear: In solid we don't have a createSuspenseQuery and as far as I understand createQuery is equevialent to useSuspenseQuery in React, because it uses createResource under the hood which automatically deals with supense boundaries.
I have already investigated the code behind a bit, but the createQuery function is quite long and complex with many sub functions and so on therefore I hoped for someone that already has the overview and know-how about how this function works and can fix this issue for me.
Hello! Thanks for opening this issue. I'm taking a look at this now. It looks like a bug. I'll report back with my findings today
Hello! An update on this. https://www.solidjs.com/guides/server#ssr-caveats
Because we cant update signals or memos from nested reacted scope during an SSR render, the enabled flag updating isn't tracked in the SSR environment. This is the reason why you see the query being picked up on the client. Now the only other way we can preserve reactivity on SSR is using resources.
The way Solid Query is currently authored, this change will take some significant refactoring to work. I'm working on a potential fix but this might take a few days to correctly implement and test it. Any ideas to fix it or PRs are always welcome!
Thanks for looking into this @ardeora 👍 are there any ideas how to change the api to allow for such behavior?
@ardeora are there any updates?
Now the only other way we can preserve reactivity on SSR is using resources.
@ardeora can you explain more specifically what you meant by that, maybe I can create a PR