diff --git a/.changeset/config.json b/.changeset/config.json index f509481bd3..5df93c3614 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -5,7 +5,22 @@ "access": "public", "baseBranch": "v4", "updateInternalDependencies": "patch", - "fixed": [], + "fixed": [ + [ + "@tanstack/eslint-plugin-query", + "@tanstack/query-async-storage-persister", + "@tanstack/query-broadcast-client-experimental", + "@tanstack/query-core", + "@tanstack/query-persist-client-core", + "@tanstack/query-sync-storage-persister", + "@tanstack/react-query", + "@tanstack/react-query-devtools", + "@tanstack/react-query-persist-client", + "@tanstack/solid-query", + "@tanstack/svelte-query", + "@tanstack/vue-query" + ] + ], "linked": [], "ignore": [], "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { diff --git a/.changeset/fast-snails-clap.md b/.changeset/fast-snails-clap.md new file mode 100644 index 0000000000..294ebe9d14 --- /dev/null +++ b/.changeset/fast-snails-clap.md @@ -0,0 +1,5 @@ +--- +'@tanstack/react-query': minor +--- + +feat(react-query): backport usePrefetchQuery, usePrefetchInfiniteQuery diff --git a/packages/react-query/src/__tests__/usePrefetchInfiniteQuery.types.test.tsx b/packages/react-query/src/__tests__/usePrefetchInfiniteQuery.types.test.tsx new file mode 100644 index 0000000000..46fe41820b --- /dev/null +++ b/packages/react-query/src/__tests__/usePrefetchInfiniteQuery.types.test.tsx @@ -0,0 +1,45 @@ +import { expectTypeOf } from 'expect-type' +import { usePrefetchInfiniteQuery } from '../usePrefetchInfiniteQuery' +import { doNotExecute } from './utils' + +describe('usePrefetchInfiniteQuery', () => { + it('should return nothing', () => { + doNotExecute(() => { + const result = usePrefetchInfiniteQuery({ + queryKey: ['key'], + queryFn: () => Promise.resolve(5), + getNextPageParam: () => 1, + }) + + expectTypeOf(result).toEqualTypeOf() + }) + }) + + it('should not allow refetchInterval, enabled or throwOnError options', () => { + doNotExecute(() => { + usePrefetchInfiniteQuery({ + queryKey: ['key'], + queryFn: () => Promise.resolve(5), + getNextPageParam: () => 1, + // @ts-expect-error TS2353 + refetchInterval: 1000, + }) + + usePrefetchInfiniteQuery({ + queryKey: ['key'], + queryFn: () => Promise.resolve(5), + getNextPageParam: () => 1, + // @ts-expect-error TS2353 + enabled: true, + }) + + usePrefetchInfiniteQuery({ + queryKey: ['key'], + queryFn: () => Promise.resolve(5), + getNextPageParam: () => 1, + // @ts-expect-error TS2353 + throwOnError: true, + }) + }) + }) +}) diff --git a/packages/react-query/src/__tests__/usePrefetchQuery.types.test.tsx b/packages/react-query/src/__tests__/usePrefetchQuery.types.test.tsx new file mode 100644 index 0000000000..73b967c657 --- /dev/null +++ b/packages/react-query/src/__tests__/usePrefetchQuery.types.test.tsx @@ -0,0 +1,56 @@ +import { expectTypeOf } from 'expect-type' +import { usePrefetchQuery } from '..' +import { doNotExecute } from './utils' + +describe('usePrefetchQuery', () => { + it('should return nothing', () => { + doNotExecute(() => { + const result = usePrefetchQuery({ + queryKey: ['key'], + queryFn: () => Promise.resolve(5), + }) + + expectTypeOf(result).toEqualTypeOf() + }) + }) + + it('should not allow refetchInterval, enabled or throwOnError options', () => { + doNotExecute(() => { + usePrefetchQuery({ + queryKey: ['key'], + queryFn: () => Promise.resolve(5), + // @ts-expect-error TS2345 + refetchInterval: 1000, + }) + + usePrefetchQuery({ + queryKey: ['key'], + queryFn: () => Promise.resolve(5), + // @ts-expect-error TS2345 + enabled: true, + }) + + usePrefetchQuery({ + queryKey: ['key'], + queryFn: () => Promise.resolve(5), + // @ts-expect-error TS2345 + throwOnError: true, + }) + }) + }) + + it('should not allow skipToken in queryFn', () => { + doNotExecute(() => { + usePrefetchQuery({ + queryKey: ['key'], + // @ts-expect-error + queryFn: skipToken, + }) + usePrefetchQuery({ + queryKey: ['key'], + // @ts-expect-error + queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5), + }) + }) + }) +}) diff --git a/packages/react-query/src/index.ts b/packages/react-query/src/index.ts index b4fbe8b403..d04d91e70f 100644 --- a/packages/react-query/src/index.ts +++ b/packages/react-query/src/index.ts @@ -46,3 +46,5 @@ export { useIsMutating } from './useIsMutating' export { useMutation } from './useMutation' export { useInfiniteQuery } from './useInfiniteQuery' export { useIsRestoring, IsRestoringProvider } from './isRestoring' +export { usePrefetchQuery } from './usePrefetchQuery' +export { usePrefetchInfiniteQuery } from './usePrefetchInfiniteQuery' diff --git a/packages/react-query/src/usePrefetchInfiniteQuery.ts b/packages/react-query/src/usePrefetchInfiniteQuery.ts new file mode 100644 index 0000000000..c7a5165312 --- /dev/null +++ b/packages/react-query/src/usePrefetchInfiniteQuery.ts @@ -0,0 +1,23 @@ +import { useQueryClient } from './QueryClientProvider' +import type { + FetchInfiniteQueryOptions, + QueryKey, + WithRequired, +} from '@tanstack/query-core' + +export function usePrefetchInfiniteQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + options: WithRequired< + FetchInfiniteQueryOptions, + 'queryKey' + >, +) { + const client = useQueryClient() + if (!client.getQueryState(options.queryKey)) { + client.prefetchInfiniteQuery(options) + } +} diff --git a/packages/react-query/src/usePrefetchQuery.ts b/packages/react-query/src/usePrefetchQuery.ts new file mode 100644 index 0000000000..ba78a8b248 --- /dev/null +++ b/packages/react-query/src/usePrefetchQuery.ts @@ -0,0 +1,23 @@ +import { useQueryClient } from './QueryClientProvider' +import type { + FetchQueryOptions, + QueryKey, + WithRequired, +} from '@tanstack/query-core' + +export function usePrefetchQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + options: WithRequired< + FetchQueryOptions, + 'queryKey' + >, +) { + const client = useQueryClient() + if (!client.getQueryState(options.queryKey)) { + client.prefetchQuery(options) + } +}