HydrationBoundary double fetching on subsequent visits
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.
- For the first visit, since it's a new query, it got hydrated in
React.useMemo - For subsequent visits, it will be deferred to
React.useEffect, however, if the cache is stale, query client will refetch beforeuseEffect, 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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