TanStack / TanStack/query

HydrationBoundary double fetching on subsequent visits

Open
#9,610 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
50.3k
Forks
4.2k
Avg merge
18h 25m
Merged PRs (30d)
200

Description

Describe the bug

I used HydrationBoundary in React Router. In loader(), I get the data, dehydrate it, then hydrate the client side query client.

  1. For the first visit, since it's a new query, it got hydrated in React.useMemo
  2. For subsequent visits, it will be deferred to React.useEffect, however, if the cache is stale, query client will refetch before useEffect, which makes the server compute the data twice: one in loader, the other in the component

I looked into the source code and found that it's due to refetchOnMount, which is true by default. I think it would be plausible to prevent a refetch if the query in the dehydrated state is fresh.

There are some experiments in the provided code, e.g. initialData from React Query meets React Router, initialData + initialDataUpdatedAt, HydrationBoundary, and my custom hook use-hydrated-query which sets refetchOnMount to false for that query if not explicitly provided during hydration. You may navigate away and back for each experiment and see the log in console to reproduce the issue.

Your minimal, reproducible example

https://stackblitz.com/edit/vitejs-vite-yiggax3s

Steps to reproduce

mentioned in 'Describe the bug'

Expected behavior

If query is fresh from loader(), client side query client should not refetch

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

Any browser

Tanstack Query adapter

react-query

TanStack Query version

v5.85.3

TypeScript version

5.8.3

Additional context

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the StackBlitz reproduction and trace the loader, HydrationBoundary, React.useMemo/useEffect, and refetchOnMount behavior while navigating away and back. Confirm the server computes fresh dehydrated data twice, then verify that a fresh query from the loader does not refetch on the client before hydration completes.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.