Skip to content

Commit 5874b2f

Browse files
authored
docs: SSR/prefetching docs fixes (#6110)
* docs(vue-query): add back old prefetching docs for vue * docs(react-query): update suspense prefetching example
1 parent d0f7238 commit 5874b2f

File tree

2 files changed

+60
-6
lines changed

2 files changed

+60
-6
lines changed

docs/react/guides/prefetching.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,17 +174,29 @@ This starts fetching `'article-comments'` immediately and flattens the waterfall
174174
1. |> getArticleCommentsById()
175175
```
176176

177-
If you want to prefetch together with Suspense, make sure the prefetches still use `useQuery` so you don't suspend and unnecessarily wait for that data, and that those prefetches happen before any suspenseful query so they can start as early as possible.
177+
If you want to prefetch together with Suspense, you will have to do things a bit differently. You can't use `useSuspenseQueries` to prefetch, since the prefetch would block the component from rendering. You also can not use `useQuery` for the prefetch, because that wouldn't start the prefetch until after suspenseful query had resolved. What you can do is add a small `usePrefetchQuery` function (we might add this to the library itself at a later point):
178178

179-
You can still use `useSuspenseQuery` in the component that actually needs the data. You _might_ want to wrap this later component in its own `<Suspense>` boundary so the "secondary" query we are prefetching does not block rendering of the "primary" data.
179+
```tsx
180+
const usePrefetchQuery = (...args) => {
181+
const queryClient = useQueryClient()
182+
183+
// This happens in render, but is safe to do because ensureQueryData
184+
// only fetches if there is no data in the cache for this query. This
185+
// means we know no observers are watching the data so the side effect
186+
// is not observable, which is safe.
187+
queryClient.ensureQueryData(...args)
188+
}
189+
```
190+
191+
This approach works with both `useQuery` and `useSuspenseQuery`, so feel free to use it as an alternative to the `useQuery({ ..., notifyOnChangeProps: [] })` approach as well. The only tradeoff is that the above function will never fetch and _update_ existing data in the cache if it's stale, but this will usually happen in the later query anyway.
192+
193+
You can now use `useSuspenseQuery` in the component that actually needs the data. You _might_ want to wrap this later component in its own `<Suspense>` boundary so the "secondary" query we are prefetching does not block rendering of the "primary" data.
180194

181195
```tsx
182196
// Prefetch
183-
useQuery({
197+
usePrefetchQuery({
184198
queryKey: ['article-comments', id],
185199
queryFn: getArticleCommentsById,
186-
// Optional optimization to avoid rerenders when this query changes:
187-
notifyOnChangeProps: [],
188200
})
189201

190202
const { data: articleResult } = useSuspenseQuery({

docs/vue/guides/prefetching.md

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,47 @@
11
---
22
id: prefetching
33
title: Prefetching
4-
ref: docs/react/guides/prefetching.md
54
---
5+
6+
If you're lucky enough, you may know enough about what your users will do to be able to prefetch the data they need before it's needed! If this is the case, you can use the `prefetchQuery` method to prefetch the results of a query to be placed into the cache:
7+
8+
[//]: # 'ExamplePrefetching'
9+
10+
```tsx
11+
const prefetchTodos = async () => {
12+
// The results of this query will be cached like a normal query
13+
await queryClient.prefetchQuery({
14+
queryKey: ['todos'],
15+
queryFn: fetchTodos,
16+
})
17+
}
18+
```
19+
20+
[//]: # 'ExamplePrefetching'
21+
22+
- If **fresh** data for this query is already in the cache, the data will not be fetched
23+
- If a `staleTime` is passed eg. `prefetchQuery({ queryKey: ['todos'], queryFn: fn, staleTime: 5000 })` and the data is older than the specified `staleTime`, the query will be fetched
24+
- If no instances of `useQuery` appear for a prefetched query, it will be deleted and garbage collected after the time specified in `gcTime`.
25+
26+
## Prefetching Infinite Queries
27+
28+
Infinite Queries can be prefetched like regular Queries. Per default, only the first page of the Query will be prefetched and will be stored under the given QueryKey. If you want to prefetch more than one page, you can use the `pages` option, in which case you also have to provide a `getNextPageParam` function:
29+
30+
[//]: # 'ExampleInfiniteQuery'
31+
32+
```tsx
33+
const prefetchTodos = async () => {
34+
// The results of this query will be cached like a normal query
35+
await queryClient.prefetchInfiniteQuery({
36+
queryKey: ['projects'],
37+
queryFn: fetchProjects,
38+
initialPageParam: 0,
39+
getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
40+
pages: 3, // prefetch the first 3 pages
41+
})
42+
}
43+
```
44+
45+
[//]: # 'ExampleInfiniteQuery'
46+
47+
The above code will try to prefetch 3 pages in order, and `getNextPageParam` will be executed for each page to determine the next page to prefetch. If `getNextPageParam` returns `undefined`, the prefetching will stop.

0 commit comments

Comments
 (0)