Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/query-handles-devtools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@tanstack/query-core': minor
'@tanstack/query-devtools': minor
---

Show in the devtools how experimental query handles started their queries. In development, `experimental_getQueryStartInfo` returns which handle function started a query, where and when, and whether anything has read it since. Production builds record nothing. The devtools show this, mark queries that a reader of an `experimental_waterfallHandle` handle first fetched, and flag prefetched queries that nothing read. In development, `dehydrate` warns when it leaves out a pending query that a handle function started on the server.
14 changes: 13 additions & 1 deletion docs/framework/react/guides/query-handles.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Readers get the query's data from the cache. To get defined `data`, read the han

## Waterfalls: `experimental_waterfallHandle`

Sometimes you only know the input during render, like a search term or a page a user clicks to. `experimental_waterfallHandle` builds the handle for such an input. It doesn't start the query: the component that reads the handle does, when it renders. That makes it a [request waterfall](./request-waterfalls.md), and the name keeps that visible. It is a plain function, not a hook, so you can call it anywhere.
Sometimes you only know the input during render, like a search term or a page a user clicks to. `experimental_waterfallHandle` builds the handle for such an input. It doesn't start the query: the component that reads the handle does, when it renders. That makes it a [request waterfall](./request-waterfalls.md), and the name keeps that visible. It is a plain function, not a hook, so you can call it anywhere. The devtools mark these queries with a `waterfall` badge.

Pass it an input:

Expand Down Expand Up @@ -174,6 +174,8 @@ const queryClient = new QueryClient({

[//]: # 'DehydratePending'

In development, `dehydrate` warns once when a server render leaves out a pending query that a handle function started and no earlier `dehydrate` call sent, because the browser would fetch it again.

### Server `staleTime`

Queries started on the server follow the same `staleTime` rules as in the browser. The data a server render sends along is as old as the server fetch, and when the browser reads it, a query with the default `staleTime: 0` already counts as stale. The component that reads it refetches on mount, so each request runs twice: once on the server and once in the browser.
Expand Down Expand Up @@ -286,3 +288,13 @@ export function dehydrateUnsent(queryClient: QueryClient) {
Every request the server handles shares the module. Once one request has sent a query, every later request for any user skips it, so their pages arrive without its data and fetch it again in the browser. The set also grows for as long as the server runs.

Each query goes out once, with the state it has when `dehydrate` first includes it. If it changes later in the same request, the change doesn't reach the browser.

## Devtools

In development, the query devtools show how each handle's query started:

- **Started by** shows the function that started the query and whether it ran on the server or in the browser. Queries that `hydrate` restores from a server render keep the server's record.
- A **waterfall** badge marks queries that a component first fetched by reading a handle from `experimental_waterfallHandle`.
- **Prefetched, never read** marks queries that a handle function started and no component has read since. That usually means a loader prefetches data the page no longer uses.

Core only records this in development, so the devtools show none of it in a production build.
1 change: 1 addition & 0 deletions packages/query-core/src/__tests__/hydration.test-d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ describe('hydration', () => {
| 'promise'
| 'meta'
| 'queryType'
| 'experimental_start'
>()
})
})
Expand Down
Loading
Loading