diff --git a/docs/src/pages/guides/infinite-queries.md b/docs/src/pages/guides/infinite-queries.md index 9c22aa65c0..b1ad518850 100644 --- a/docs/src/pages/guides/infinite-queries.md +++ b/docs/src/pages/guides/infinite-queries.md @@ -43,8 +43,8 @@ With this information, we can create a "Load More" UI by: import { useInfiniteQuery } from 'react-query' function Projects() { - const fetchProjects = (key, cursor = 0) => - fetch('/api/projects?cursor=' + cursor) + const fetchProjects = ({ pageParam = 0 }) => + fetch('/api/projects?cursor=' + pageParam) const { data, @@ -98,8 +98,8 @@ By default, the variable returned from `getNextPageParam` will be supplied to th ```js function Projects() { - const fetchProjects = (key, cursor = 0) => - fetch('/api/projects?cursor=' + cursor) + const fetchProjects = ({ pageParam = 0 }) => + fetch('/api/projects?cursor=' + pageParam) const { status, diff --git a/docs/src/pages/guides/migrating-to-react-query-3.md b/docs/src/pages/guides/migrating-to-react-query-3.md index 423a48ab75..7890a5971f 100644 --- a/docs/src/pages/guides/migrating-to-react-query-3.md +++ b/docs/src/pages/guides/migrating-to-react-query-3.md @@ -65,6 +65,32 @@ const queryClient = new QueryClient({ }) ``` +### Query function parameters + +Query functions now get a `QueryFunctionContext` instead of the query key parameters. + +The `QueryFunctionContext` contains a `queryKey` and a `pageParam` in case of ininite queries. + +useQuery: + +```js +// Old +useQuery(['post', id], (_key, id) => fetchPost(id)) + +// New +useQuery(['post', id], () => fetchPost(id)) +``` + +useInfiniteQuery: + +```js +// Old +useInfiniteQuery(['posts'], (_key, pageParam = 0) => fetchPosts(pageParam)) + +// New +useInfiniteQuery(['posts'], ({ pageParam = 0 }) => fetchPost(pageParam)) +``` + ### usePaginatedQuery() The `usePaginatedQuery()` hook has been replaced by the `keepPreviousData` option on `useQuery`: @@ -93,9 +119,13 @@ const { fetchNextPage, hasNextPage, isFetchingNextPage, -} = useInfiniteQuery('projects', fetchProjects, { - getNextPageParam: (lastPage, pages) => lastPage.nextCursor, -}) +} = useInfiniteQuery( + 'projects', + ({ pageParam = 0 }) => fetchProjects(pageParam), + { + getNextPageParam: (lastPage, pages) => lastPage.nextCursor, + } +) ``` Both directions: @@ -109,10 +139,14 @@ const { hasPreviousPage, isFetchingNextPage, isFetchingPreviousPage, -} = useInfiniteQuery('projects', fetchProjects, { - getNextPageParam: (lastPage, pages) => lastPage.nextCursor, - getPreviousPageParam: (firstPage, pages) => firstPage.prevCursor, -}) +} = useInfiniteQuery( + 'projects', + ({ pageParam = 0 }) => fetchProjects(pageParam), + { + getNextPageParam: (lastPage, pages) => lastPage.nextCursor, + getPreviousPageParam: (firstPage, pages) => firstPage.prevCursor, + } +) ``` One direction reversed: @@ -123,13 +157,17 @@ const { fetchNextPage, hasNextPage, isFetchingNextPage, -} = useInfiniteQuery('projects', fetchProjects, { - select: data => ({ - pages: [...data.pages].reverse(), - pageParams: [...data.pageParams].reverse(), - }), - getNextPageParam: (lastPage, pages) => lastPage.nextCursor, -}) +} = useInfiniteQuery( + 'projects', + ({ pageParam = 0 }) => fetchProjects(pageParam), + { + select: data => ({ + pages: [...data.pages].reverse(), + pageParams: [...data.pageParams].reverse(), + }), + getNextPageParam: (lastPage, pages) => lastPage.nextCursor, + } +) ``` Manually removing the first page: @@ -276,6 +314,12 @@ The `forceFetchOnMount` query option has been replaced by `refetchOnMount: 'alwa When `refetchOnMount` was set to `false` any additional components were prevented from refetching on mount. In version 3 only the component where the option has been set will not refetch on mount. +### QueryOptions.queryFnParamsFilter + +The `queryFnParamsFilter` option has been removed because query functions now get a `QueryFunctionContext` object instead of the query key. + +Parameters can still be filtered within the query function itself as the `QueryFunctionContext` also contains the query key. + ### QueryResult.clear() The `QueryResult.clear()` method has been renamed to `QueryResult.remove()`. diff --git a/docs/src/pages/guides/paginated-queries.md b/docs/src/pages/guides/paginated-queries.md index bf2e53c954..abdea69ab8 100644 --- a/docs/src/pages/guides/paginated-queries.md +++ b/docs/src/pages/guides/paginated-queries.md @@ -27,7 +27,7 @@ Consider the following example where we would ideally want to increment a pageIn function Todos() { const [page, setPage] = React.useState(0) - const fetchProjects = (key, page = 0) => fetch('/api/projects?page=' + page) + const fetchProjects = (page = 0) => fetch('/api/projects?page=' + page) const { isLoading, @@ -36,7 +36,7 @@ function Todos() { data, isFetching, isPreviousData, - } = useQuery(['projects', page], fetchProjects) + } = useQuery(['projects', page], () => fetchProjects(page)) return (
diff --git a/docs/src/pages/guides/query-functions.md b/docs/src/pages/guides/query-functions.md index 34c6c0d9d4..f2dfa04f92 100644 --- a/docs/src/pages/guides/query-functions.md +++ b/docs/src/pages/guides/query-functions.md @@ -46,7 +46,7 @@ useQuery(['todos', todoId], async () => { ## Query Function Variables -Query keys are not just for uniquely identifying the data you are fetching, but are also conveniently passed as variables for your query function and while not always necessary, this makes it possible to extract your query functions if needed. The individual parts of the query key get passed through to your query function as parameters in the same order they appear in the array key: +Query keys are not just for uniquely identifying the data you are fetching, but are also conveniently passed into your query function and while not always necessary, this makes it possible to extract your query functions if needed: ```js function Todos({ completed }) { @@ -54,23 +54,9 @@ function Todos({ completed }) { } // Access the key, status and page variables in your query function! -function fetchTodoList(key, { status, page }) { +function fetchTodoList({ queryKey }) { + const { status, page } = queryKey[1] return new Promise() - // ... -} -``` - -If you send through more items in your query key, they will also be available in your query function: - -```js -function Todo({ todoId, preview }) { - const result = useQuery(['todo', todoId, { preview }], fetchTodoById) -} - -// Access status and page in your query function! -function fetchTodoById(key, todoId, { preview }) { - return new Promise() - // ... } ``` diff --git a/docs/src/pages/reference/useInfiniteQuery.md b/docs/src/pages/reference/useInfiniteQuery.md index 178cef8109..62ee6ebd15 100644 --- a/docs/src/pages/reference/useInfiniteQuery.md +++ b/docs/src/pages/reference/useInfiniteQuery.md @@ -4,9 +4,6 @@ title: useInfiniteQuery --- ```js - -const queryFn = (...queryKey, pageParam) // => Promise - const { fetchNextPage, fetchPreviousPage, @@ -15,10 +12,10 @@ const { isFetchingNextPage, isFetchingPreviousPage, ...result -} = useInfiniteQuery(queryKey, queryFn, { +} = useInfiniteQuery(queryKey, ({ pageParam = 1 }) => fetchPage(pageParam), { ...options, getNextPageParam: (lastPage, allPages) => lastPage.nextCursor, - getPreviousPageParam: (firstPage, allPages) => firstPage.prevCursor + getPreviousPageParam: (firstPage, allPages) => firstPage.prevCursor, }) ``` @@ -26,6 +23,13 @@ const { The options for `useInfiniteQuery` are identical to the [`useQuery` hook](#usequery) with the addition of the following: +- `queryFn: (context: QueryFunctionContext) => Promise` + - **Required, but only if no default query function has been defined** + - The function that the query will use to request data. + - Receives a `QueryFunctionContext` object with the following variables: + - `queryKey: QueryKey` + - `pageParam: unknown | undefined` + - Must return a promise that will either resolves data or throws an error. - `getNextPageParam: (lastPage, allPages) => unknown | undefined` - When new data is received for this query, this function receives both the last page of the infinite list of data and the full array of all pages. - It should return a **single variable** that will be passed as the last optional parameter to your query function. diff --git a/docs/src/pages/reference/useQuery.md b/docs/src/pages/reference/useQuery.md index 5db3210c9d..17539963a6 100644 --- a/docs/src/pages/reference/useQuery.md +++ b/docs/src/pages/reference/useQuery.md @@ -32,7 +32,6 @@ const { onError, onSettled, onSuccess, - queryFnParamsFilter, queryKeyHashFn, refetchInterval, refetchIntervalInBackground, @@ -63,11 +62,11 @@ const result = useQuery({ - The query key to use for this query. - The query key will be hashed into a stable hash. See [Query Keys](./guides/query-keys) for more information. - The query will automatically update when this key changes (as long as `enabled` is not set to `false`). -- `queryFn: (...params: unknown[]) => Promise` +- `queryFn: (context: QueryFunctionContext) => Promise` - **Required, but only if no default query function has been defined** - The function that the query will use to request data. - - Receives the following variables in the order that they are provided: - - Query Key parameters + - Receives a `QueryFunctionContext` object with the following variables: + - `queryKey: QueryKey` - Must return a promise that will either resolves data or throws an error. - `enabled: boolean` - Set this to `false` to disable this query from automatically running. @@ -149,10 +148,6 @@ const result = useQuery({ - Optional - Defaults to `false` - If set, any previous `data` will be kept when fetching new data because the query key changed. -- `queryFnParamsFilter: (...params: unknown[]) => unknown[]` - - Optional - - This function will filter the params that get passed to `queryFn`. - - For example, you can filter out the first query key from the params by using `queryFnParamsFilter: params => params.slice(1)`. - `structuralSharing: boolean` - Optional - Defaults to `true` @@ -174,6 +169,10 @@ const result = useQuery({ - A derived boolean from the `status` variable above, provided for convenience. - `isError: boolean` - A derived boolean from the `status` variable above, provided for convenience. +- `isLoadingError: boolean` + - Will be `true` if the query failed while fetching for the first time. +- `isRefetchError: boolean` + - Will be `true` if the query failed while refetching. - `data: TData` - Defaults to `undefined`. - The last successfully resolved data for the query. diff --git a/examples/basic/src/index.js b/examples/basic/src/index.js index fce9fac7fb..da3d16b330 100644 --- a/examples/basic/src/index.js +++ b/examples/basic/src/index.js @@ -90,7 +90,7 @@ function Posts({ setPostId }) { ); } -const getPostById = async (key, id) => { +const getPostById = async (id) => { const { data } = await axios.get( `https://jsonplaceholder.typicode.com/posts/${id}` ); @@ -98,7 +98,7 @@ const getPostById = async (key, id) => { }; function usePost(postId) { - return useQuery(["post", postId], getPostById, { + return useQuery(["post", postId], () => getPostById(postId), { enabled: !!postId, }); } diff --git a/examples/custom-hooks/src/hooks/usePost.js b/examples/custom-hooks/src/hooks/usePost.js index a943e5f5c4..b6a38c2c93 100644 --- a/examples/custom-hooks/src/hooks/usePost.js +++ b/examples/custom-hooks/src/hooks/usePost.js @@ -1,7 +1,7 @@ import { useQuery } from "react-query"; import axios from "axios"; -const getPostById = async (_, postId) => { +const getPostById = async (postId) => { const { data } = await axios.get( `https://jsonplaceholder.typicode.com/posts/${postId}` ); @@ -9,5 +9,5 @@ const getPostById = async (_, postId) => { }; export default function usePost(postId) { - return useQuery(["post", postId], getPostById); + return useQuery(["post", postId], () => getPostById(postId)); } diff --git a/examples/default-query-function/src/index.js b/examples/default-query-function/src/index.js index 1e902c89f7..7909b77b7e 100644 --- a/examples/default-query-function/src/index.js +++ b/examples/default-query-function/src/index.js @@ -11,9 +11,9 @@ import { import { ReactQueryDevtools } from "react-query-devtools"; // Define a default query function that will receive the query key -const defaultQueryFn = async (key) => { +const defaultQueryFn = async ({ queryKey }) => { const { data } = await axios.get( - `https://jsonplaceholder.typicode.com${key}` + `https://jsonplaceholder.typicode.com${queryKey[0]}` ); return data; }; diff --git a/examples/load-more-infinite-scroll/pages/index.js b/examples/load-more-infinite-scroll/pages/index.js index c7126b2b5c..745506521e 100755 --- a/examples/load-more-infinite-scroll/pages/index.js +++ b/examples/load-more-infinite-scroll/pages/index.js @@ -30,8 +30,8 @@ function Example() { hasNextPage, } = useInfiniteQuery( 'projects', - async (_key, nextId = 0) => { - const res = await axios.get('/api/projects?cursor=' + nextId) + async ({ pageParam = 0 }) => { + const res = await axios.get('/api/projects?cursor=' + pageParam) return res.data }, { diff --git a/examples/nextjs/hooks/usePosts/index.js b/examples/nextjs/hooks/usePosts/index.js index 7031dadfff..8ead3ffbf1 100644 --- a/examples/nextjs/hooks/usePosts/index.js +++ b/examples/nextjs/hooks/usePosts/index.js @@ -1,16 +1,14 @@ import ky from 'ky-universal' import { useQuery } from 'react-query' -const fetchPosts = async (_, limit) => { - const offset = limit ?? 10 - +const fetchPosts = async (limit = 10) => { const parsed = await ky('https://jsonplaceholder.typicode.com/posts').json() - const result = parsed.filter(x => x.id <= offset) + const result = parsed.filter(x => x.id <= limit) return result } const usePosts = limit => { - return useQuery(['posts', limit], fetchPosts) + return useQuery(['posts', limit], () => fetchPosts(limit)) } export { usePosts, fetchPosts } diff --git a/examples/pagination/pages/index.js b/examples/pagination/pages/index.js index 788e91b441..d9b1a86c1d 100644 --- a/examples/pagination/pages/index.js +++ b/examples/pagination/pages/index.js @@ -22,14 +22,14 @@ function Example() { const queryClient = useQueryClient() const [page, setPage] = React.useState(0) - const fetchProjects = React.useCallback(async (key, page = 0) => { + const fetchProjects = React.useCallback(async (page = 0) => { const { data } = await axios.get('/api/projects?page=' + page) return data }, []) const { status, data, error, isFetching, isPreviousData } = useQuery( ['projects', page], - fetchProjects, + () => fetchProjects(page), { keepPreviousData: true } ) diff --git a/examples/playground/src/index.js b/examples/playground/src/index.js index 6b2464d4d9..ad4d804467 100644 --- a/examples/playground/src/index.js +++ b/examples/playground/src/index.js @@ -181,7 +181,7 @@ function Todos({ initialFilter = "", setEditingIndex }) { const { status, data, isFetching, error, failureCount, refetch } = useQuery( ["todos", { filter }], - fetchTodos + () => fetchTodos({ filter }) ); return ( @@ -235,7 +235,7 @@ function EditTodo({ editingIndex, setEditingIndex }) { // Don't attempt to query until editingIndex is truthy const { status, data, isFetching, error, failureCount, refetch } = useQuery( ["todo", { id: editingIndex }], - fetchTodoById, + () => fetchTodoById({ id: editingIndex }), { enabled: editingIndex !== null, } @@ -370,7 +370,7 @@ function AddTodo() { ); } -function fetchTodos(key, { filter } = {}) { +function fetchTodos({ filter } = {}) { console.info("fetchTodos", { filter }); const promise = new Promise((resolve, reject) => { setTimeout(() => { @@ -388,7 +388,7 @@ function fetchTodos(key, { filter } = {}) { return promise; } -function fetchTodoById(key, { id }) { +function fetchTodoById({ id }) { console.info("fetchTodoById", { id }); return new Promise((resolve, reject) => { setTimeout(() => { diff --git a/examples/prefetching/pages/[user]/[repo].js b/examples/prefetching/pages/[user]/[repo].js index c6ec99a393..d22b92d5da 100755 --- a/examples/prefetching/pages/[user]/[repo].js +++ b/examples/prefetching/pages/[user]/[repo].js @@ -10,7 +10,7 @@ export default () => { const { status, data, error, isFetching } = useQuery( ['team', id], - (key, id) => fetch('/api/data?id=' + id) + () => fetch('/api/data?id=' + id) ) return ( diff --git a/examples/prefetching/pages/index.js b/examples/prefetching/pages/index.js index b79e180ae9..06425541f6 100755 --- a/examples/prefetching/pages/index.js +++ b/examples/prefetching/pages/index.js @@ -14,7 +14,7 @@ const getCharacters = async () => { return data } -const getCharacter = async (key, selectedChar) => { +const getCharacter = async (selectedChar) => { await new Promise(r => setTimeout(r, 500)) const { data } = await axios.get( `https://rickandmortyapi.com/api/character/${selectedChar}` @@ -41,7 +41,7 @@ function Example() { const { data: selectedData } = useQuery( ['character', selectedChar], - getCharacter + () => getCharacter(selectedChar) ) const prefetchNext = async id => { diff --git a/src/core/infiniteQueryBehavior.ts b/src/core/infiniteQueryBehavior.ts index 21bc1d8d96..878ddc83ef 100644 --- a/src/core/infiniteQueryBehavior.ts +++ b/src/core/infiniteQueryBehavior.ts @@ -1,5 +1,5 @@ import type { QueryBehavior } from './query' -import type { InfiniteData, QueryOptions } from './types' +import type { InfiniteData, QueryFunctionContext, QueryOptions } from './types' export function infiniteQueryBehavior< TData, @@ -8,7 +8,7 @@ export function infiniteQueryBehavior< >(): QueryBehavior, TError, TQueryFnData> { return { onFetch: context => { - context.queryFn = () => { + context.fetchFn = () => { const fetchMore = context.fetchOptions?.meta?.fetchMore const pageParam = fetchMore?.pageParam const isFetchingNextPage = fetchMore?.direction === 'forward' @@ -32,8 +32,13 @@ export function infiniteQueryBehavior< return Promise.resolve(pages) } + const queryFnContext: QueryFunctionContext = { + queryKey: context.queryKey, + pageParam: param, + } + return Promise.resolve() - .then(() => queryFn(...context.params, param)) + .then(() => queryFn(queryFnContext)) .then(page => { newPageParams = previous ? [param, ...newPageParams] diff --git a/src/core/query.ts b/src/core/query.ts index 36574cdff0..b434096e17 100644 --- a/src/core/query.ts +++ b/src/core/query.ts @@ -9,10 +9,10 @@ import { } from './utils' import type { InitialDataFunction, - QueryFunction, QueryKey, QueryOptions, QueryStatus, + QueryFunctionContext, } from './types' import type { QueryCache } from './queryCache' import type { QueryObserver } from './queryObserver' @@ -47,11 +47,11 @@ export interface QueryState { } export interface FetchContext { - state: QueryState - options: QueryOptions - params: unknown[] + fetchFn: () => unknown | Promise fetchOptions?: FetchOptions - queryFn: QueryFunction + options: QueryOptions + queryKey: QueryKey + state: QueryState } export interface QueryBehavior< @@ -338,25 +338,26 @@ export class Query { } } - // Get the query function params - let params = ensureArray(this.queryKey) - - const filter = this.options.queryFnParamsFilter - params = filter ? filter(params) : params + // Create query function context + const queryKey = ensureArray(this.queryKey) + const queryFnContext: QueryFunctionContext = { + queryKey, + pageParam: undefined, + } - // Get query function - const queryFn = () => + // Create fetch function + const fetchFn = () => this.options.queryFn - ? this.options.queryFn(...params) + ? this.options.queryFn(queryFnContext) : Promise.reject('Missing queryFn') // Trigger behavior hook const context: FetchContext = { fetchOptions, options: this.options, - params, + queryKey, state: this.state, - queryFn, + fetchFn, } if (this.options.behavior?.onFetch) { @@ -373,7 +374,7 @@ export class Query { // Try to fetch the data this.retryer = new Retryer({ - fn: context.queryFn, + fn: context.fetchFn, onFail: () => { this.dispatch({ type: 'failed' }) }, diff --git a/src/core/queryClient.ts b/src/core/queryClient.ts index 83d7872fb4..9bbf6de775 100644 --- a/src/core/queryClient.ts +++ b/src/core/queryClient.ts @@ -317,7 +317,7 @@ export class QueryClient { getQueryDefaults( queryKey?: QueryKey - ): QueryObserverOptions | undefined { + ): QueryObserverOptions | undefined { return queryKey ? this.queryDefaults.find(x => partialMatchKey(queryKey, x.queryKey)) ?.defaultOptions @@ -348,7 +348,7 @@ export class QueryClient { : undefined } - defaultQueryOptions>(options?: T): T { + defaultQueryOptions>(options?: T): T { if (options?._defaulted) { return options } @@ -360,9 +360,9 @@ export class QueryClient { } as T } - defaultQueryObserverOptions>( - options?: T - ): T { + defaultQueryObserverOptions< + T extends QueryObserverOptions + >(options?: T): T { return this.defaultQueryOptions(options) } diff --git a/src/core/types.ts b/src/core/types.ts index d5747a6498..0b82281903 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -5,7 +5,14 @@ import type { QueryFilters } from './utils' export type QueryKey = string | unknown[] -export type QueryFunction = (...args: any[]) => T | Promise +export type QueryFunction = ( + context: QueryFunctionContext +) => T | Promise + +export interface QueryFunctionContext { + queryKey: QueryKey + pageParam?: TPageParam +} export type InitialDataFunction = () => T | undefined @@ -18,12 +25,12 @@ export type QueryKeyHashFunction = (queryKey: QueryKey) => string export type GetPreviousPageParamFunction = ( firstPage: TQueryFnData, allPages: TQueryFnData[] -) => unknown | undefined +) => unknown export type GetNextPageParamFunction = ( lastPage: TQueryFnData, allPages: TQueryFnData[] -) => unknown | undefined +) => unknown export interface InfiniteData { pages: TData[] @@ -49,7 +56,6 @@ export interface QueryOptions< queryHash?: string queryKey?: QueryKey queryKeyHashFn?: QueryKeyHashFunction - queryFnParamsFilter?: (args: unknown[]) => unknown[] initialData?: TData | InitialDataFunction behavior?: QueryBehavior /** diff --git a/src/core/utils.ts b/src/core/utils.ts index 4c7dad6490..dffaf2655d 100644 --- a/src/core/utils.ts +++ b/src/core/utils.ts @@ -88,7 +88,7 @@ export function timeUntilStale(updatedAt: number, staleTime?: number): number { return Math.max(updatedAt + (staleTime || 0) - Date.now(), 0) } -export function parseQueryArgs>( +export function parseQueryArgs>( arg1: QueryKey | TOptions, arg2?: QueryFunction | TOptions, arg3?: TOptions diff --git a/src/hydration/tests/react.test.tsx b/src/hydration/tests/react.test.tsx index 47871e344d..70a371fa3f 100644 --- a/src/hydration/tests/react.test.tsx +++ b/src/hydration/tests/react.test.tsx @@ -14,7 +14,7 @@ describe('React hydration', () => { beforeAll(async () => { const queryCache = new QueryCache() const queryClient = new QueryClient({ queryCache }) - await queryClient.prefetchQuery('string', dataQuery) + await queryClient.prefetchQuery('string', () => dataQuery('string')) const dehydrated = dehydrate(queryClient) stringifiedState = JSON.stringify(dehydrated) queryClient.clear() @@ -28,7 +28,7 @@ describe('React hydration', () => { function Page() { useHydrate(dehydratedState) - const { data } = useQuery('string', dataQuery) + const { data } = useQuery('string', () => dataQuery('string')) return (

{data}

@@ -55,7 +55,7 @@ describe('React hydration', () => { const queryClient = new QueryClient({ queryCache }) function Page({ queryKey }: { queryKey: string }) { - const { data } = useQuery(queryKey, dataQuery) + const { data } = useQuery(queryKey, () => dataQuery(queryKey)) return (

{data}

@@ -81,7 +81,9 @@ describe('React hydration', () => { await intermediateClient.prefetchQuery('string', () => dataQuery('should change') ) - await intermediateClient.prefetchQuery('added string', dataQuery) + await intermediateClient.prefetchQuery('added string', () => + dataQuery('added string') + ) const dehydrated = dehydrate(intermediateClient) intermediateClient.clear() @@ -110,7 +112,7 @@ describe('React hydration', () => { const queryClient = new QueryClient({ queryCache }) function Page() { - const { data } = useQuery('string', dataQuery) + const { data } = useQuery('string', () => dataQuery('string')) return (

{data}

diff --git a/src/react/tests/ssr.test.tsx b/src/react/tests/ssr.test.tsx index e5e57201d6..0fcc19af11 100644 --- a/src/react/tests/ssr.test.tsx +++ b/src/react/tests/ssr.test.tsx @@ -89,13 +89,9 @@ describe('Server Side Rendering', () => { function Page() { const [page, setPage] = React.useState(1) - const { data } = useQuery( - [key, page], - async (_: string, pageArg: number) => { - return pageArg - }, - { initialData: 1 } - ) + const { data } = useQuery([key, page], async () => page, { + initialData: 1, + }) return (
diff --git a/src/react/tests/useInfiniteQuery.test.tsx b/src/react/tests/useInfiniteQuery.test.tsx index 0e53082803..025600ff12 100644 --- a/src/react/tests/useInfiniteQuery.test.tsx +++ b/src/react/tests/useInfiniteQuery.test.tsx @@ -57,7 +57,7 @@ describe('useInfiniteQuery', () => { function Page() { const state = useInfiniteQuery( key, - (_key: string, pageParam: number = 0) => pageParam, + ({ pageParam = 0 }) => Number(pageParam), { getNextPageParam: lastPage => lastPage + 1, } @@ -137,11 +137,11 @@ describe('useInfiniteQuery', () => { const start = 1 const state = useInfiniteQuery( key, - async (_key, pageParam: number = start) => { + async ({ pageParam = start }) => { if (pageParam === 2) { throw new Error('error') } - return pageParam + return Number(pageParam) }, { retry: 1, @@ -180,9 +180,9 @@ describe('useInfiniteQuery', () => { const state = useInfiniteQuery( [key, order], - async (_key, orderParam, pageParam = 0) => { + async ({ pageParam = 0 }) => { await sleep(10) - return `${pageParam}-${orderParam}` + return `${pageParam}-${order}` }, { getNextPageParam: () => 1, @@ -300,7 +300,7 @@ describe('useInfiniteQuery', () => { function Page() { const state = useInfiniteQuery( key, - (_key, pageParam: number = 0) => pageParam, + ({ pageParam = 0 }) => Number(pageParam), { select: data => ({ pages: [...data.pages].reverse(), @@ -353,9 +353,9 @@ describe('useInfiniteQuery', () => { const start = 10 const state = useInfiniteQuery( key, - async (_key, pageParam: number = start) => { + async ({ pageParam = start }) => { await sleep(10) - return pageParam + return Number(pageParam) }, { getPreviousPageParam: firstPage => firstPage - 1, @@ -423,9 +423,8 @@ describe('useInfiniteQuery', () => { const states: UseInfiniteQueryResult[] = [] function Page() { - const state = useInfiniteQuery( - key, - (_key, pageParam: number = 10) => pageParam + const state = useInfiniteQuery(key, ({ pageParam = 10 }) => + Number(pageParam) ) states.push(state) @@ -513,7 +512,7 @@ describe('useInfiniteQuery', () => { function Page() { const state = useInfiniteQuery( key, - (_key, pageParam: number = 10) => pageParam, + ({ pageParam = 10 }) => Number(pageParam), { getPreviousPageParam: firstPage => firstPage - 1, getNextPageParam: lastPage => lastPage + 1, @@ -606,9 +605,9 @@ describe('useInfiniteQuery', () => { const start = 10 const state = useInfiniteQuery( key, - async (_key, pageParam: number = start) => { + async ({ pageParam = start }) => { await sleep(50) - return pageParam + return Number(pageParam) }, { getNextPageParam: lastPage => lastPage + 1, @@ -681,9 +680,9 @@ describe('useInfiniteQuery', () => { const start = 10 const state = useInfiniteQuery( key, - async (_key, pageParam: number = start) => { + async ({ pageParam = start }) => { await sleep(50) - return pageParam + return Number(pageParam) }, { getNextPageParam: lastPage => lastPage + 1, @@ -731,9 +730,9 @@ describe('useInfiniteQuery', () => { function Page() { const state = useInfiniteQuery( key, - async (_key, pageParam: number = 0) => { + async ({ pageParam = 0 }) => { await sleep(10) - return pageParam + return Number(pageParam) }, { getNextPageParam: lastPage => lastPage + 1, @@ -797,9 +796,9 @@ describe('useInfiniteQuery', () => { const state = useInfiniteQuery( key, - async (_key, pageParam: number = firstPage) => { + async ({ pageParam = firstPage }) => { await sleep(10) - return pageParam + return Number(pageParam) }, { getNextPageParam: lastPage => lastPage + 1, @@ -883,9 +882,13 @@ describe('useInfiniteQuery', () => { const states: UseInfiniteQueryResult[] = [] function Page() { - const state = useInfiniteQuery(key, (_key, pageParam = 1) => pageParam, { - getNextPageParam: () => undefined, - }) + const state = useInfiniteQuery( + key, + ({ pageParam = 1 }) => Number(pageParam), + { + getNextPageParam: () => undefined, + } + ) states.push(state) @@ -918,7 +921,7 @@ describe('useInfiniteQuery', () => { const states: UseInfiniteQueryResult[] = [] function Page() { - const state = useInfiniteQuery(key, (_key, pageParam = 10) => pageParam, { + const state = useInfiniteQuery(key, ({ pageParam = 10 }) => pageParam, { initialData: { pages: [10], pageParams: [undefined] }, getNextPageParam: lastPage => (lastPage === 10 ? 11 : undefined), }) @@ -954,7 +957,7 @@ describe('useInfiniteQuery', () => { const states: UseInfiniteQueryResult[] = [] function Page() { - const state = useInfiniteQuery(key, (_key, pageParam = 10) => pageParam, { + const state = useInfiniteQuery(key, ({ pageParam = 10 }) => pageParam, { initialData: { pages: [10], pageParams: [undefined] }, getNextPageParam: () => undefined, }) @@ -1014,8 +1017,8 @@ describe('useInfiniteQuery', () => { refetch, } = useInfiniteQuery( key, - (_key, nextId = 0) => - fetchItemsWithLimit(nextId, fetchCountRef.current++), + ({ pageParam = 0 }) => + fetchItemsWithLimit(pageParam, fetchCountRef.current++), { getNextPageParam: lastPage => lastPage.nextId, } @@ -1141,11 +1144,11 @@ describe('useInfiniteQuery', () => { refetch, } = useInfiniteQuery( key, - (_key, nextId = 0) => + ({ pageParam = 0 }) => fetchItems( - nextId, + pageParam, fetchCountRef.current++, - nextId === MAX || (nextId === MAX - 1 && isRemovedLastPage) + pageParam === MAX || (pageParam === MAX - 1 && isRemovedLastPage) ), { getNextPageParam: lastPage => lastPage.nextId, diff --git a/src/react/tests/useQuery.test.tsx b/src/react/tests/useQuery.test.tsx index c7e7251600..d59287860b 100644 --- a/src/react/tests/useQuery.test.tsx +++ b/src/react/tests/useQuery.test.tsx @@ -49,32 +49,6 @@ describe('useQuery', () => { expectType(withError.data) expectType(withError.error) - // it should be possible to specify the query function arguments - useQuery(key, arg1 => { - expectType(arg1) - }) - - // the query function arguments should default to unknown - useQuery(key, arg1 => { - expectType(arg1) - }) - - // the query function arguments should default to any if other generics are provided - useQuery(key, arg1 => { - expectType(arg1) - arg1.someMethod() - }) - - // it should be possible to specify the query function argument types - useQuery(key, (arg1: string) => { - expectType(arg1) - }) - - // it should be possible to specify the query function argument types when generics are provided - useQuery(key, (arg1: string) => { - expectType(arg1) - }) - // it should provide the result type in the configuration useQuery([key], async () => true, { onSuccess: data => expectType(data), @@ -1700,7 +1674,7 @@ describe('useQuery', () => { renderWithClient(queryClient, ) - expect(queryFn).toHaveBeenCalledWith(key, variables) + expect(queryFn).toHaveBeenCalledWith({ queryKey: [key, variables] }) }) it('should not refetch query on focus when `enabled` is set to `false`', async () => { @@ -2658,7 +2632,7 @@ describe('useQuery', () => { it('should accept an empty string as query key', async () => { function Page() { - const result = useQuery('', (key: string) => key) + const result = useQuery('', ctx => ctx.queryKey) return <>{JSON.stringify(result.data)} } @@ -2669,13 +2643,13 @@ describe('useQuery', () => { it('should accept an object as query key', async () => { function Page() { - const result = useQuery([{ a: 'a' }], (key: { a: string }) => key) + const result = useQuery([{ a: 'a' }], ctx => ctx.queryKey) return <>{JSON.stringify(result.data)} } const rendered = renderWithClient(queryClient, ) - await waitFor(() => rendered.getByText('{"a":"a"}')) + await waitFor(() => rendered.getByText('[{"a":"a"}]')) }) it('should refetch if any query instance becomes enabled', async () => {