TanStack / query

🤖 Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.
https://tanstack.com/query
MIT License
39.76k stars 2.66k forks source link

SSR using NextJS App Router with InitialData Does not Callback #7294

Closed MrDesjardins closed 2 weeks ago

MrDesjardins commented 2 weeks ago

Describe the bug

When setting the useQuery with initialData when the key change, the callback function is not called.

Your minimal, reproducible example

https://codesandbox.io/p/devbox/usequeryinitialdata-lmvygc?file=%2Fapp%2Fchild.tsx

Steps to reproduce

  1. Create a useQuery
const { data } = useQuery(
    ["key", counter],
    async (): Promise<string> => {
      console.log("Execute useQuery");
      return "test: " + Math.random().toString();
    },
    {
      initialData: "Hardcoded Initial Data",
      refetchOnWindowFocus: false,
      refetchOnReconnect: false,
      staleTime: Infinity,
    },
  );
  1. Make sure the key change for each query
  2. Make the key change
  3. The async function of the useQuery should be invoked
  4. Remove the initialData
  5. The code behaves as expected and the function is invoked

Expected behavior

As a user I expect that if the key is new that the callback async function is triggered when initialData is set or not.

How often does this bug happen?

Every time

Screenshots or Videos

https://github.com/TanStack/query/assets/1014796/c650ecab-3473-4552-91db-91afda5ee90b

Platform

macOs, Chrome (latest)

Tanstack Query adapter

None

TanStack Query version

4.35.7

TypeScript version

5

Additional context

Codesandbox: https://codesandbox.io/p/devbox/usequeryinitialdata-lmvygc?file=%2Fapp%2Fchild.tsx%3A16%2C9

TkDodo commented 2 weeks ago

initialData is always taken into account when a new cache entry is created. If you change the key, you get a new cache entry. Thus, all your keys (["key", 1], ["key", 2]etc) will get"Hardcoded Initial Data"put into the cache. And then, you're saying that data in the cache is fresh forever (staleTime: Infinity), so there's no need to run thequeryFn`.

MrDesjardins commented 1 week ago

@TkDodo What would be the suggested configuration to get initial data from SSR and then subsequent calls to update that data? I've read the documentation, it says that initialData can be used as long as it is passed along the React components, thus I though I could use it to fill the cache from the SSR.

For additional context, the real use case is a grid with filters. The filters change the cache key but on the initial load (server) there is some data for the grid.

TkDodo commented 1 week ago

it says that initialData can be used as long as it is passed along the React components

have you read the guide along with all the drawbacks of initialData?

you likely want hydration:

MrDesjardins commented 1 week ago

@TkDodo I have read the documentation and people in my team as well.

We are not using V5 yet and we all understood that we could use initialData without adding the hydration API into our code base. If we must use hydration, we can but will need to plan additional time for the task. It's fine, if that is the direction but we were under the impression that we could make it work direclty with the initialData