query icon indicating copy to clipboard operation
query copied to clipboard

Bug: Dependent Query doesn't work with solid-js SSR

Open BierDav opened this issue 1 year ago • 8 comments

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

  1. Open codesandbox
  2. Run ´pnpm dev`
  3. Open the preview
  4. Now the server waits for 2 seconds before responding because of the timout query in src/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.
  5. This causes that the client has to fetch the remaining state query. You can see that in the dev tools: image

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

BierDav avatar Jun 04 '24 09:06 BierDav

@ardeora FYI

TkDodo avatar Jun 04 '24 15:06 TkDodo

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 avatar Jun 04 '24 15:06 TkDodo

@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.

BierDav avatar Jun 04 '24 19:06 BierDav

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

ardeora avatar Jun 04 '24 20:06 ardeora

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!

ardeora avatar Jun 10 '24 04:06 ardeora

Thanks for looking into this @ardeora 👍 are there any ideas how to change the api to allow for such behavior?

BierDav avatar Jul 17 '24 16:07 BierDav

@ardeora are there any updates?

BierDav avatar Sep 18 '24 07:09 BierDav

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

BierDav avatar Nov 26 '24 07:11 BierDav