Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ensureQueryData): add 'revalidateIfStale' option #6996

Merged
merged 21 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
76cd6a7
feat(fetchQuery): add 'prefetchWhenStale' option
andredewaard Feb 29, 2024
435e4c8
Merge branch 'main' into main
TkDodo Mar 3, 2024
9df8571
Revert "feat(fetchQuery): add 'prefetchWhenStale' option"
andredewaard Mar 4, 2024
7fba325
Merge remote-tracking branch 'refs/remotes/origin/main'
andredewaard Mar 4, 2024
1e9899b
fetch(ensureQueryData): Add revalidateIfStale option
andredewaard Mar 4, 2024
45ecbe5
Merge branch 'main' into main
TkDodo Mar 4, 2024
e442b4f
fetch(ensureQueryData): Add revalidateIfStale option
andredewaard Mar 4, 2024
5a0b4e1
Merge remote-tracking branch 'refs/remotes/origin/main'
andredewaard Mar 4, 2024
412b20f
fetch(ensureQueryData): Add revalidateIfStale option
andredewaard Mar 4, 2024
b81f170
test(ensureQueryClient) implemented test for new option 'revalidateIf…
andredewaard Mar 4, 2024
818b2e3
Merge branch 'main' into main
TkDodo Mar 9, 2024
441bd04
Update packages/query-core/src/queryClient.ts
TkDodo Mar 9, 2024
a9c297d
Merge branch 'main' into main
TkDodo Mar 9, 2024
f94753a
Merge branch 'main' into main
TkDodo Mar 9, 2024
08ca13f
Merge branch 'main' into main
TkDodo Mar 9, 2024
e206c1d
Merge branch 'main' into main
TkDodo Mar 12, 2024
c4a35bf
Merge remote-tracking branch 'refs/remotes/origin/main'
andredewaard Mar 12, 2024
5881195
feat(fetchQuery): formatted file
andredewaard Mar 12, 2024
473a149
Merge branch 'main' into main
TkDodo Mar 13, 2024
f2ca914
Update docs/reference/QueryClient.md
TkDodo Mar 13, 2024
90aa502
chore: prettier
TkDodo Mar 13, 2024
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
3 changes: 2 additions & 1 deletion docs/reference/QueryClient.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ const data = await queryClient.ensureQueryData({ queryKey, queryFn })

**Options**

- The options for `ensureQueryData` are exactly the same as those of [`fetchQuery`](#queryclientfetchquery) except that `queryKey` is required.
- The options for `ensureQueryData` are almost the same as those of [`fetchQuery`](#queryclientfetchquery) except that `queryKey` is required and that is has an extra optional option `revalidateIfStale`. When set `revalidateIfStale` to true the function will make sure the data will refetch in the background while still returning the data from the cache.
TkDodo marked this conversation as resolved.
Show resolved Hide resolved


**Returns**

Expand Down
20 changes: 16 additions & 4 deletions packages/query-core/src/queryClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type {
DefaultError,
DefaultOptions,
DefaultedQueryObserverOptions,
EnsureQueryDataOptions,
FetchInfiniteQueryOptions,
FetchQueryOptions,
InfiniteData,
Expand Down Expand Up @@ -130,13 +131,24 @@ export class QueryClient {
TData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
>(
options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
options: EnsureQueryDataOptions<TQueryFnData, TError, TData, TQueryKey>,
): Promise<TData> {
const cachedData = this.getQueryData<TData>(options.queryKey)

return cachedData !== undefined
? Promise.resolve(cachedData)
: this.fetchQuery(options)
if (cachedData === undefined) return this.fetchQuery(options)
else {
const defaultedOptions = this.defaultQueryOptions(options)
const query = this.#queryCache.build(this, defaultedOptions)

if (
options.revalidateIfStale &&
query.isStaleByTime(defaultedOptions.staleTime)
) {
void this.prefetchQuery(defaultedOptions)
}

return Promise.resolve(cachedData)
}
}

getQueriesData<TQueryFnData = unknown>(
Expand Down
18 changes: 18 additions & 0 deletions packages/query-core/src/tests/queryClient.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,24 @@ describe('queryClient', () => {
queryClient.ensureQueryData({ queryKey: [key], queryFn }),
).resolves.toEqual('data')
})

test('should return the cached query data if the query is found and preFetchQuery in the background when revalidateIfStale is set', async () => {
const TIMEOUT = 10
const key = queryKey()
queryClient.setQueryData([key, 'id'], 'old')

const queryFn = () => new Promise((resolve) => {
setTimeout(() => resolve('new'), TIMEOUT)
})

await expect(
queryClient.ensureQueryData({ queryKey: [key, 'id'], queryFn, revalidateIfStale: true }),
).resolves.toEqual('old')
await sleep(TIMEOUT + 10)
await expect(
queryClient.ensureQueryData({ queryKey: [key, 'id'], queryFn, revalidateIfStale: true }),
).resolves.toEqual('new')
})
})

describe('getQueriesData', () => {
Expand Down
17 changes: 17 additions & 0 deletions packages/query-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,23 @@ export interface FetchQueryOptions<
staleTime?: number
}

export interface EnsureQueryDataOptions<
TQueryFnData = unknown,
TError = DefaultError,
TData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
TPageParam = never,
> extends FetchQueryOptions<
TQueryFnData,
TError,
TData,
TQueryKey,
TPageParam
> {
revalidateIfStale?: boolean
TkDodo marked this conversation as resolved.
Show resolved Hide resolved
}


type FetchInfiniteQueryPages<TQueryFnData = unknown, TPageParam = unknown> =
| { pages?: never }
| {
Expand Down
Loading