Skip to content

Race condition causing hydration error when streaming with server components #9642

@brettpostin

Description

@brettpostin

Describe the bug

I'm following the guidance here to implement streaming with server components.

I'm prefetching data like so (note, no await):

const streamingQueryClient = getQueryClient();
streamingQueryClient.prefetchQuery({
  queryKey: ['roles-client-streaming'],
  queryFn: () => getRoles(),
});

And inside a client component:

export default function ClientComponentWithStreaming() {
  const { data, isFetching, status, isStale, fetchStatus } = useSuspenseQuery({
    queryKey: ['roles-client-streaming'],
    queryFn: getRolesClient,
  });

  console.log('data', data);
  console.log('isFetching', isFetching);
  console.log('status', status);
  console.log('isStale', isStale);
  console.log('fetchStatus', fetchStatus);

  return (
    <>
      <ul className="list-disc pl-5 mt-4">
        {data &&
          data!.map((item: any) => (
            <li key={item.id} className="mb-2">
              {item.name}
            </li>
          ))}
      </ul>
      {isFetching && <LoadingPanel />}
    </>
  );
}

The issue i'm seeing is that intermittently, isFetching and isStale are true on first client render. This causes a hydration error as it tries to render the LoadingPanel.

In my actual app, this is not intermittent and reproducible on every page load.

During server side rendering, the console logs are as follows:

data Array(1)
isFetching false
status success
isStale false
fetchStatus idle

So i would not expect the first client paint to be in a fetching state. However, when the hydration error occurs, the logs in the browser on the client show as:

data [{…}]
isFetching true
status success
isStale true
fetchStatus fetching

Under what conditions would the first client render be in a fetching state if the data is already prefetched via a promise?

Your minimal, reproducible example

https://github.com/brettpostin/tanstack-query-hydration-issue

Steps to reproduce

  1. Pull and run repo
  2. Keep refreshing until you hit the hydration error

Expected behavior

I would expect the first client paint to not be in a fetching state if the data is present in the cache from a prefetch.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

  • OS: Windows
  • Browser: Edge
  • TanStack Query Version: 5.87.4

Tanstack Query adapter

react-query

TanStack Query version

5.87.4

TypeScript version

No response

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions