@tanstack/react-query 5.0.0-alpha.71 → 5.0.0-alpha.84
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/codemods/remove-overloads/remove-overloads.js +1 -1
- package/build/codemods/src/v4/key-transformation.js +1 -1
- package/build/codemods/src/v4/replace-import-specifier.js +1 -1
- package/build/lib/HydrationBoundary.cjs.map +1 -1
- package/build/lib/HydrationBoundary.d.ts.map +1 -1
- package/build/lib/HydrationBoundary.js.map +1 -1
- package/build/lib/HydrationBoundary.legacy.cjs.map +1 -1
- package/build/lib/HydrationBoundary.legacy.js.map +1 -1
- package/build/lib/__tests__/utils.d.ts +1 -1
- package/build/lib/__tests__/utils.d.ts.map +1 -1
- package/build/lib/errorBoundaryUtils.cjs.map +1 -1
- package/build/lib/errorBoundaryUtils.d.ts.map +1 -1
- package/build/lib/errorBoundaryUtils.js.map +1 -1
- package/build/lib/errorBoundaryUtils.legacy.cjs.map +1 -1
- package/build/lib/errorBoundaryUtils.legacy.js.map +1 -1
- package/build/lib/suspense.cjs.map +1 -1
- package/build/lib/suspense.d.ts +1 -1
- package/build/lib/suspense.d.ts.map +1 -1
- package/build/lib/suspense.js.map +1 -1
- package/build/lib/suspense.legacy.cjs.map +1 -1
- package/build/lib/suspense.legacy.js.map +1 -1
- package/build/lib/types.d.ts +1 -1
- package/build/lib/types.d.ts.map +1 -1
- package/build/lib/useBaseQuery.cjs.map +1 -1
- package/build/lib/useBaseQuery.d.ts +1 -1
- package/build/lib/useBaseQuery.d.ts.map +1 -1
- package/build/lib/useBaseQuery.js.map +1 -1
- package/build/lib/useBaseQuery.legacy.cjs.map +1 -1
- package/build/lib/useBaseQuery.legacy.js.map +1 -1
- package/build/lib/useInfiniteQuery.cjs.map +1 -1
- package/build/lib/useInfiniteQuery.d.ts +1 -1
- package/build/lib/useInfiniteQuery.d.ts.map +1 -1
- package/build/lib/useInfiniteQuery.js.map +1 -1
- package/build/lib/useInfiniteQuery.legacy.cjs.map +1 -1
- package/build/lib/useInfiniteQuery.legacy.js.map +1 -1
- package/build/lib/useIsFetching.cjs.map +1 -1
- package/build/lib/useIsFetching.d.ts.map +1 -1
- package/build/lib/useIsFetching.js.map +1 -1
- package/build/lib/useIsFetching.legacy.cjs.map +1 -1
- package/build/lib/useIsFetching.legacy.js.map +1 -1
- package/build/lib/useMutation.cjs.map +1 -1
- package/build/lib/useMutation.d.ts +1 -1
- package/build/lib/useMutation.d.ts.map +1 -1
- package/build/lib/useMutation.js.map +1 -1
- package/build/lib/useMutation.legacy.cjs.map +1 -1
- package/build/lib/useMutation.legacy.js.map +1 -1
- package/build/lib/useMutationState.cjs.map +1 -1
- package/build/lib/useMutationState.d.ts +1 -1
- package/build/lib/useMutationState.d.ts.map +1 -1
- package/build/lib/useMutationState.js.map +1 -1
- package/build/lib/useMutationState.legacy.cjs.map +1 -1
- package/build/lib/useMutationState.legacy.js.map +1 -1
- package/build/lib/useQueries.cjs.map +1 -1
- package/build/lib/useQueries.d.ts +1 -1
- package/build/lib/useQueries.d.ts.map +1 -1
- package/build/lib/useQueries.js.map +1 -1
- package/build/lib/useQueries.legacy.cjs.map +1 -1
- package/build/lib/useQueries.legacy.js.map +1 -1
- package/build/lib/useQuery.cjs.map +1 -1
- package/build/lib/useQuery.d.ts +1 -1
- package/build/lib/useQuery.d.ts.map +1 -1
- package/build/lib/useQuery.js.map +1 -1
- package/build/lib/useQuery.legacy.cjs.map +1 -1
- package/build/lib/useQuery.legacy.js.map +1 -1
- package/package.json +2 -2
- package/src/HydrationBoundary.tsx +1 -1
- package/src/__tests__/HydrationBoundary.test.tsx +5 -5
- package/src/__tests__/QueryClientProvider.test.tsx +2 -2
- package/src/__tests__/QueryResetErrorBoundary.test.tsx +2 -2
- package/src/__tests__/ssr-hydration.test.tsx +2 -2
- package/src/__tests__/ssr.test.tsx +2 -2
- package/src/__tests__/suspense.test.tsx +2 -2
- package/src/__tests__/useInfiniteQuery.test.tsx +36 -74
- package/src/__tests__/useInfiniteQuery.type.test.tsx +2 -2
- package/src/__tests__/useIsFetching.test.tsx +1 -1
- package/src/__tests__/useMutation.test.tsx +2 -2
- package/src/__tests__/useQueries.test.tsx +8 -8
- package/src/__tests__/useQuery.test.tsx +138 -37
- package/src/__tests__/useQuery.types.test.tsx +1 -1
- package/src/__tests__/utils.tsx +2 -2
- package/src/errorBoundaryUtils.ts +2 -2
- package/src/suspense.ts +1 -1
- package/src/types.ts +5 -5
- package/src/useBaseQuery.ts +3 -3
- package/src/useInfiniteQuery.ts +5 -5
- package/src/useIsFetching.ts +1 -1
- package/src/useMutation.ts +3 -3
- package/src/useMutationState.ts +5 -5
- package/src/useQueries.ts +11 -11
- package/src/useQuery.ts +2 -2
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { fireEvent, render, waitFor } from '@testing-library/react'
|
|
2
2
|
import * as React from 'react'
|
|
3
3
|
|
|
4
|
+
import { vi } from 'vitest'
|
|
5
|
+
import { QueryCache, keepPreviousData, useInfiniteQuery } from '..'
|
|
4
6
|
import {
|
|
5
7
|
createQueryClient,
|
|
6
8
|
queryKey,
|
|
@@ -13,8 +15,6 @@ import type {
|
|
|
13
15
|
QueryFunctionContext,
|
|
14
16
|
UseInfiniteQueryResult,
|
|
15
17
|
} from '..'
|
|
16
|
-
import { QueryCache, useInfiniteQuery, keepPreviousData } from '..'
|
|
17
|
-
import { vi } from 'vitest'
|
|
18
18
|
import type { Mock } from 'vitest'
|
|
19
19
|
|
|
20
20
|
interface Result {
|
|
@@ -213,7 +213,7 @@ describe('useInfiniteQuery', () => {
|
|
|
213
213
|
|
|
214
214
|
await waitFor(() => rendered.getByText('data: 0-asc'))
|
|
215
215
|
await waitFor(() => rendered.getByText('isFetching: false'))
|
|
216
|
-
await waitFor(() => expect(states.length).toBe(
|
|
216
|
+
await waitFor(() => expect(states.length).toBe(6))
|
|
217
217
|
|
|
218
218
|
expect(states[0]).toMatchObject({
|
|
219
219
|
data: undefined,
|
|
@@ -251,15 +251,7 @@ describe('useInfiniteQuery', () => {
|
|
|
251
251
|
isSuccess: true,
|
|
252
252
|
isPlaceholderData: true,
|
|
253
253
|
})
|
|
254
|
-
// Hook state update
|
|
255
254
|
expect(states[5]).toMatchObject({
|
|
256
|
-
data: { pages: ['0-desc', '1-desc'] },
|
|
257
|
-
isFetching: true,
|
|
258
|
-
isFetchingNextPage: false,
|
|
259
|
-
isSuccess: true,
|
|
260
|
-
isPlaceholderData: true,
|
|
261
|
-
})
|
|
262
|
-
expect(states[6]).toMatchObject({
|
|
263
255
|
data: { pages: ['0-asc'] },
|
|
264
256
|
isFetching: false,
|
|
265
257
|
isFetchingNextPage: false,
|
|
@@ -606,77 +598,47 @@ describe('useInfiniteQuery', () => {
|
|
|
606
598
|
|
|
607
599
|
it('should silently cancel any ongoing fetch when fetching more', async () => {
|
|
608
600
|
const key = queryKey()
|
|
609
|
-
const states: UseInfiniteQueryResult<InfiniteData<number>>[] = []
|
|
610
601
|
|
|
611
602
|
function Page() {
|
|
612
603
|
const start = 10
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
states.push(state)
|
|
625
|
-
|
|
626
|
-
const { refetch, fetchNextPage } = state
|
|
627
|
-
|
|
628
|
-
React.useEffect(() => {
|
|
629
|
-
setActTimeout(() => {
|
|
630
|
-
refetch()
|
|
631
|
-
}, 100)
|
|
632
|
-
setActTimeout(() => {
|
|
633
|
-
fetchNextPage()
|
|
634
|
-
}, 110)
|
|
635
|
-
}, [fetchNextPage, refetch])
|
|
604
|
+
const { data, fetchNextPage, refetch, status, fetchStatus } =
|
|
605
|
+
useInfiniteQuery({
|
|
606
|
+
queryKey: key,
|
|
607
|
+
queryFn: async ({ pageParam }) => {
|
|
608
|
+
await sleep(50)
|
|
609
|
+
return Number(pageParam)
|
|
610
|
+
},
|
|
611
|
+
defaultPageParam: start,
|
|
612
|
+
getNextPageParam: (lastPage) => lastPage + 1,
|
|
613
|
+
})
|
|
636
614
|
|
|
637
|
-
return
|
|
615
|
+
return (
|
|
616
|
+
<div>
|
|
617
|
+
<button onClick={() => fetchNextPage()}>fetchNextPage</button>
|
|
618
|
+
<button onClick={() => refetch()}>refetch</button>
|
|
619
|
+
<div>data: {JSON.stringify(data)}</div>
|
|
620
|
+
<div>
|
|
621
|
+
status: {status}, {fetchStatus}
|
|
622
|
+
</div>
|
|
623
|
+
</div>
|
|
624
|
+
)
|
|
638
625
|
}
|
|
639
626
|
|
|
640
|
-
renderWithClient(queryClient, <Page />)
|
|
627
|
+
const rendered = renderWithClient(queryClient, <Page />)
|
|
641
628
|
|
|
642
|
-
await
|
|
629
|
+
await waitFor(() => rendered.getByText('status: success, idle'))
|
|
630
|
+
await waitFor(() =>
|
|
631
|
+
rendered.getByText('data: {"pages":[10],"pageParams":[10]}'),
|
|
632
|
+
)
|
|
643
633
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
expect(states[1]).toMatchObject({
|
|
653
|
-
hasNextPage: true,
|
|
654
|
-
data: { pages: [10] },
|
|
655
|
-
isFetching: false,
|
|
656
|
-
isFetchingNextPage: false,
|
|
657
|
-
isSuccess: true,
|
|
658
|
-
})
|
|
659
|
-
expect(states[2]).toMatchObject({
|
|
660
|
-
hasNextPage: true,
|
|
661
|
-
data: { pages: [10] },
|
|
662
|
-
isFetching: true,
|
|
663
|
-
isFetchingNextPage: false,
|
|
664
|
-
isSuccess: true,
|
|
665
|
-
})
|
|
666
|
-
expect(states[3]).toMatchObject({
|
|
667
|
-
hasNextPage: true,
|
|
668
|
-
data: { pages: [10] },
|
|
669
|
-
isFetching: true,
|
|
670
|
-
isFetchingNextPage: true,
|
|
671
|
-
isSuccess: true,
|
|
672
|
-
})
|
|
673
|
-
expect(states[4]).toMatchObject({
|
|
674
|
-
hasNextPage: true,
|
|
675
|
-
data: { pages: [10, 11] },
|
|
676
|
-
isFetching: false,
|
|
677
|
-
isFetchingNextPage: false,
|
|
678
|
-
isSuccess: true,
|
|
679
|
-
})
|
|
634
|
+
fireEvent.click(rendered.getByRole('button', { name: /refetch/i }))
|
|
635
|
+
await waitFor(() => rendered.getByText('status: success, fetching'))
|
|
636
|
+
fireEvent.click(rendered.getByRole('button', { name: /fetchNextPage/i }))
|
|
637
|
+
|
|
638
|
+
await waitFor(() => rendered.getByText('status: success, idle'))
|
|
639
|
+
await waitFor(() =>
|
|
640
|
+
rendered.getByText('data: {"pages":[10,11],"pageParams":[10,11]}'),
|
|
641
|
+
)
|
|
680
642
|
})
|
|
681
643
|
|
|
682
644
|
it('should silently cancel an ongoing fetchNextPage request when another fetchNextPage is invoked', async () => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { InfiniteData } from '@tanstack/query-core'
|
|
2
1
|
import { QueryClient } from '@tanstack/query-core'
|
|
3
2
|
import { useInfiniteQuery } from '../useInfiniteQuery'
|
|
4
3
|
import { useQuery } from '../useQuery'
|
|
5
|
-
import type { Expect, Equal } from './utils'
|
|
6
4
|
import { doNotExecute } from './utils'
|
|
5
|
+
import type { Equal, Expect } from './utils'
|
|
6
|
+
import type { InfiniteData } from '@tanstack/query-core'
|
|
7
7
|
|
|
8
8
|
describe('pageParam', () => {
|
|
9
9
|
it('defaultPageParam should define type of param passed to queryFunctionContext', () => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { fireEvent, render, waitFor } from '@testing-library/react'
|
|
2
2
|
import * as React from 'react'
|
|
3
3
|
|
|
4
|
+
import { QueryCache, useIsFetching, useQuery } from '..'
|
|
4
5
|
import {
|
|
5
6
|
createQueryClient,
|
|
6
7
|
queryKey,
|
|
@@ -8,7 +9,6 @@ import {
|
|
|
8
9
|
setActTimeout,
|
|
9
10
|
sleep,
|
|
10
11
|
} from './utils'
|
|
11
|
-
import { QueryCache, useIsFetching, useQuery } from '..'
|
|
12
12
|
|
|
13
13
|
describe('useIsFetching', () => {
|
|
14
14
|
// See https://github.com/tannerlinsley/react-query/issues/105
|
|
@@ -3,8 +3,8 @@ import '@testing-library/jest-dom'
|
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import { ErrorBoundary } from 'react-error-boundary'
|
|
5
5
|
|
|
6
|
+
import { vi } from 'vitest'
|
|
6
7
|
import { MutationCache, QueryCache, useMutation } from '..'
|
|
7
|
-
import type { UseMutationResult } from '../types'
|
|
8
8
|
import {
|
|
9
9
|
createQueryClient,
|
|
10
10
|
mockNavigatorOnLine,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
setActTimeout,
|
|
14
14
|
sleep,
|
|
15
15
|
} from './utils'
|
|
16
|
-
import {
|
|
16
|
+
import type { UseMutationResult } from '../types'
|
|
17
17
|
|
|
18
18
|
describe('useMutation', () => {
|
|
19
19
|
const queryCache = new QueryCache()
|
|
@@ -2,15 +2,7 @@ import { fireEvent, render, waitFor } from '@testing-library/react'
|
|
|
2
2
|
import * as React from 'react'
|
|
3
3
|
import { ErrorBoundary } from 'react-error-boundary'
|
|
4
4
|
|
|
5
|
-
import type { QueryFunctionContext } from '@tanstack/query-core'
|
|
6
5
|
import { vi } from 'vitest'
|
|
7
|
-
import type {
|
|
8
|
-
QueryFunction,
|
|
9
|
-
QueryKey,
|
|
10
|
-
QueryObserverResult,
|
|
11
|
-
UseQueryOptions,
|
|
12
|
-
UseQueryResult,
|
|
13
|
-
} from '..'
|
|
14
6
|
import { QueryCache, useQueries } from '..'
|
|
15
7
|
import {
|
|
16
8
|
createQueryClient,
|
|
@@ -20,6 +12,14 @@ import {
|
|
|
20
12
|
renderWithClient,
|
|
21
13
|
sleep,
|
|
22
14
|
} from './utils'
|
|
15
|
+
import type {
|
|
16
|
+
QueryFunction,
|
|
17
|
+
QueryKey,
|
|
18
|
+
QueryObserverResult,
|
|
19
|
+
UseQueryOptions,
|
|
20
|
+
UseQueryResult,
|
|
21
|
+
} from '..'
|
|
22
|
+
import type { QueryFunctionContext } from '@tanstack/query-core'
|
|
23
23
|
|
|
24
24
|
describe('useQueries', () => {
|
|
25
25
|
const queryCache = new QueryCache()
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { act, fireEvent, render, waitFor } from '@testing-library/react'
|
|
2
2
|
import '@testing-library/jest-dom'
|
|
3
3
|
import * as React from 'react'
|
|
4
|
+
import { ErrorBoundary } from 'react-error-boundary'
|
|
5
|
+
import { vi } from 'vitest'
|
|
6
|
+
import { QueryCache, keepPreviousData, useQuery } from '..'
|
|
4
7
|
import {
|
|
5
8
|
Blink,
|
|
6
9
|
createQueryClient,
|
|
@@ -19,9 +22,6 @@ import type {
|
|
|
19
22
|
UseQueryOptions,
|
|
20
23
|
UseQueryResult,
|
|
21
24
|
} from '..'
|
|
22
|
-
import { QueryCache, useQuery, keepPreviousData } from '..'
|
|
23
|
-
import { ErrorBoundary } from 'react-error-boundary'
|
|
24
|
-
import { vi } from 'vitest'
|
|
25
25
|
import type { Mock } from 'vitest'
|
|
26
26
|
|
|
27
27
|
describe('useQuery', () => {
|
|
@@ -693,17 +693,15 @@ describe('useQuery', () => {
|
|
|
693
693
|
// required to make sure no additional renders are happening after data is successfully fetched for the second time
|
|
694
694
|
await sleep(100)
|
|
695
695
|
|
|
696
|
-
expect(states.length).toBe(
|
|
696
|
+
expect(states.length).toBe(4)
|
|
697
697
|
// First load
|
|
698
698
|
expect(states[0]).toMatchObject({ isPending: true, isSuccess: false })
|
|
699
699
|
// First success
|
|
700
700
|
expect(states[1]).toMatchObject({ isPending: false, isSuccess: true })
|
|
701
701
|
// Remove
|
|
702
702
|
expect(states[2]).toMatchObject({ isPending: true, isSuccess: false })
|
|
703
|
-
// Hook state update
|
|
704
|
-
expect(states[3]).toMatchObject({ isPending: true, isSuccess: false })
|
|
705
703
|
// Second success
|
|
706
|
-
expect(states[
|
|
704
|
+
expect(states[3]).toMatchObject({ isPending: false, isSuccess: true })
|
|
707
705
|
})
|
|
708
706
|
|
|
709
707
|
it('should fetch when refetchOnMount is false and nothing has been fetched yet', async () => {
|
|
@@ -1716,7 +1714,7 @@ describe('useQuery', () => {
|
|
|
1716
1714
|
act(() => rendered.rerender(<Page count={2} />))
|
|
1717
1715
|
await waitFor(() => rendered.getByText('error: Error test'))
|
|
1718
1716
|
|
|
1719
|
-
await waitFor(() => expect(states.length).toBe(
|
|
1717
|
+
await waitFor(() => expect(states.length).toBe(6))
|
|
1720
1718
|
// Initial
|
|
1721
1719
|
expect(states[0]).toMatchObject({
|
|
1722
1720
|
data: undefined,
|
|
@@ -1741,16 +1739,8 @@ describe('useQuery', () => {
|
|
|
1741
1739
|
error: null,
|
|
1742
1740
|
isPlaceholderData: true,
|
|
1743
1741
|
})
|
|
1744
|
-
// Hook state update
|
|
1745
|
-
expect(states[3]).toMatchObject({
|
|
1746
|
-
data: 0,
|
|
1747
|
-
isFetching: true,
|
|
1748
|
-
status: 'success',
|
|
1749
|
-
error: null,
|
|
1750
|
-
isPlaceholderData: true,
|
|
1751
|
-
})
|
|
1752
1742
|
// New data
|
|
1753
|
-
expect(states[
|
|
1743
|
+
expect(states[3]).toMatchObject({
|
|
1754
1744
|
data: 1,
|
|
1755
1745
|
isFetching: false,
|
|
1756
1746
|
status: 'success',
|
|
@@ -1758,15 +1748,7 @@ describe('useQuery', () => {
|
|
|
1758
1748
|
isPlaceholderData: false,
|
|
1759
1749
|
})
|
|
1760
1750
|
// rerender Page 2
|
|
1761
|
-
expect(states[
|
|
1762
|
-
data: 1,
|
|
1763
|
-
isFetching: true,
|
|
1764
|
-
status: 'success',
|
|
1765
|
-
error: null,
|
|
1766
|
-
isPlaceholderData: true,
|
|
1767
|
-
})
|
|
1768
|
-
// Hook state update again
|
|
1769
|
-
expect(states[6]).toMatchObject({
|
|
1751
|
+
expect(states[4]).toMatchObject({
|
|
1770
1752
|
data: 1,
|
|
1771
1753
|
isFetching: true,
|
|
1772
1754
|
status: 'success',
|
|
@@ -1774,13 +1756,13 @@ describe('useQuery', () => {
|
|
|
1774
1756
|
isPlaceholderData: true,
|
|
1775
1757
|
})
|
|
1776
1758
|
// Error
|
|
1777
|
-
expect(states[
|
|
1759
|
+
expect(states[5]).toMatchObject({
|
|
1778
1760
|
data: undefined,
|
|
1779
1761
|
isFetching: false,
|
|
1780
1762
|
status: 'error',
|
|
1781
1763
|
isPlaceholderData: false,
|
|
1782
1764
|
})
|
|
1783
|
-
expect(states[
|
|
1765
|
+
expect(states[5]!.error).toHaveProperty('message', 'Error test')
|
|
1784
1766
|
})
|
|
1785
1767
|
|
|
1786
1768
|
it('should not show initial data from next query if placeholderData is set', async () => {
|
|
@@ -1825,7 +1807,7 @@ describe('useQuery', () => {
|
|
|
1825
1807
|
rendered.getByText('data: 1, count: 1, isFetching: false'),
|
|
1826
1808
|
)
|
|
1827
1809
|
|
|
1828
|
-
expect(states.length).toBe(
|
|
1810
|
+
expect(states.length).toBe(4)
|
|
1829
1811
|
|
|
1830
1812
|
// Initial
|
|
1831
1813
|
expect(states[0]).toMatchObject({
|
|
@@ -1848,15 +1830,8 @@ describe('useQuery', () => {
|
|
|
1848
1830
|
isSuccess: true,
|
|
1849
1831
|
isPlaceholderData: false,
|
|
1850
1832
|
})
|
|
1851
|
-
// Hook state update
|
|
1852
|
-
expect(states[3]).toMatchObject({
|
|
1853
|
-
data: 99,
|
|
1854
|
-
isFetching: true,
|
|
1855
|
-
isSuccess: true,
|
|
1856
|
-
isPlaceholderData: false,
|
|
1857
|
-
})
|
|
1858
1833
|
// New data
|
|
1859
|
-
expect(states[
|
|
1834
|
+
expect(states[3]).toMatchObject({
|
|
1860
1835
|
data: 1,
|
|
1861
1836
|
isFetching: false,
|
|
1862
1837
|
isSuccess: true,
|
|
@@ -3663,6 +3638,7 @@ describe('useQuery', () => {
|
|
|
3663
3638
|
})
|
|
3664
3639
|
act(() => setPrefetched(true))
|
|
3665
3640
|
}
|
|
3641
|
+
|
|
3666
3642
|
prefetch()
|
|
3667
3643
|
}, [])
|
|
3668
3644
|
|
|
@@ -5929,6 +5905,7 @@ describe('useQuery', () => {
|
|
|
5929
5905
|
</div>
|
|
5930
5906
|
)
|
|
5931
5907
|
}
|
|
5908
|
+
|
|
5932
5909
|
const rendered = renderWithClient(queryClient, <Page />)
|
|
5933
5910
|
const fetchBtn = rendered.getByRole('button', { name: 'refetch' })
|
|
5934
5911
|
await waitFor(() => rendered.getByText('data: 1'))
|
|
@@ -5989,8 +5966,132 @@ describe('useQuery', () => {
|
|
|
5989
5966
|
</div>
|
|
5990
5967
|
)
|
|
5991
5968
|
}
|
|
5969
|
+
|
|
5992
5970
|
const rendered = renderWithClient(queryClient, <Page />)
|
|
5993
5971
|
await waitFor(() => rendered.getByText('status: success'))
|
|
5994
5972
|
await waitFor(() => rendered.getByText('data: 1'))
|
|
5995
5973
|
})
|
|
5974
|
+
it('should reuse same data object reference when queryKey changes back to some cached data', async () => {
|
|
5975
|
+
const key = queryKey()
|
|
5976
|
+
const spy = vi.fn()
|
|
5977
|
+
|
|
5978
|
+
async function fetchNumber(id: number) {
|
|
5979
|
+
await sleep(5)
|
|
5980
|
+
return { numbers: { current: { id } } }
|
|
5981
|
+
}
|
|
5982
|
+
function Test() {
|
|
5983
|
+
const [id, setId] = React.useState(1)
|
|
5984
|
+
|
|
5985
|
+
const { data } = useQuery({
|
|
5986
|
+
select: selector,
|
|
5987
|
+
queryKey: [key, 'user', id],
|
|
5988
|
+
queryFn: () => fetchNumber(id),
|
|
5989
|
+
})
|
|
5990
|
+
|
|
5991
|
+
React.useEffect(() => {
|
|
5992
|
+
spy(data)
|
|
5993
|
+
}, [data])
|
|
5994
|
+
|
|
5995
|
+
return (
|
|
5996
|
+
<div>
|
|
5997
|
+
<button name="1" onClick={() => setId(1)}>
|
|
5998
|
+
1
|
|
5999
|
+
</button>
|
|
6000
|
+
<button name="2" onClick={() => setId(2)}>
|
|
6001
|
+
2
|
|
6002
|
+
</button>
|
|
6003
|
+
<span>Rendered Id: {data?.id}</span>
|
|
6004
|
+
</div>
|
|
6005
|
+
)
|
|
6006
|
+
}
|
|
6007
|
+
|
|
6008
|
+
function selector(data: any) {
|
|
6009
|
+
return data.numbers.current
|
|
6010
|
+
}
|
|
6011
|
+
|
|
6012
|
+
const rendered = renderWithClient(queryClient, <Test />)
|
|
6013
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
6014
|
+
|
|
6015
|
+
spy.mockClear()
|
|
6016
|
+
await waitFor(() => rendered.getByText('Rendered Id: 1'))
|
|
6017
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
6018
|
+
|
|
6019
|
+
spy.mockClear()
|
|
6020
|
+
fireEvent.click(rendered.getByRole('button', { name: /2/ }))
|
|
6021
|
+
await waitFor(() => rendered.getByText('Rendered Id: 2'))
|
|
6022
|
+
expect(spy).toHaveBeenCalledTimes(2) // called with undefined because id changed
|
|
6023
|
+
|
|
6024
|
+
spy.mockClear()
|
|
6025
|
+
fireEvent.click(rendered.getByRole('button', { name: /1/ }))
|
|
6026
|
+
await waitFor(() => rendered.getByText('Rendered Id: 1'))
|
|
6027
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
6028
|
+
|
|
6029
|
+
spy.mockClear()
|
|
6030
|
+
fireEvent.click(rendered.getByRole('button', { name: /2/ }))
|
|
6031
|
+
await waitFor(() => rendered.getByText('Rendered Id: 2'))
|
|
6032
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
6033
|
+
})
|
|
6034
|
+
it('should reuse same data object reference when queryKey changes and placeholderData is present', async () => {
|
|
6035
|
+
const key = queryKey()
|
|
6036
|
+
const spy = vi.fn()
|
|
6037
|
+
|
|
6038
|
+
async function fetchNumber(id: number) {
|
|
6039
|
+
await sleep(5)
|
|
6040
|
+
return { numbers: { current: { id } } }
|
|
6041
|
+
}
|
|
6042
|
+
function Test() {
|
|
6043
|
+
const [id, setId] = React.useState(1)
|
|
6044
|
+
|
|
6045
|
+
const { data } = useQuery({
|
|
6046
|
+
select: selector,
|
|
6047
|
+
queryKey: [key, 'user', id],
|
|
6048
|
+
queryFn: () => fetchNumber(id),
|
|
6049
|
+
placeholderData: { numbers: { current: { id: 99 } } },
|
|
6050
|
+
})
|
|
6051
|
+
|
|
6052
|
+
React.useEffect(() => {
|
|
6053
|
+
spy(data)
|
|
6054
|
+
}, [data])
|
|
6055
|
+
|
|
6056
|
+
return (
|
|
6057
|
+
<div>
|
|
6058
|
+
<button name="1" onClick={() => setId(1)}>
|
|
6059
|
+
1
|
|
6060
|
+
</button>
|
|
6061
|
+
<button name="2" onClick={() => setId(2)}>
|
|
6062
|
+
2
|
|
6063
|
+
</button>
|
|
6064
|
+
<span>Rendered Id: {data?.id}</span>
|
|
6065
|
+
</div>
|
|
6066
|
+
)
|
|
6067
|
+
}
|
|
6068
|
+
|
|
6069
|
+
function selector(data: any) {
|
|
6070
|
+
return data.numbers.current
|
|
6071
|
+
}
|
|
6072
|
+
|
|
6073
|
+
const rendered = renderWithClient(queryClient, <Test />)
|
|
6074
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
6075
|
+
|
|
6076
|
+
spy.mockClear()
|
|
6077
|
+
await waitFor(() => rendered.getByText('Rendered Id: 99'))
|
|
6078
|
+
await waitFor(() => rendered.getByText('Rendered Id: 1'))
|
|
6079
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
6080
|
+
|
|
6081
|
+
spy.mockClear()
|
|
6082
|
+
fireEvent.click(rendered.getByRole('button', { name: /2/ }))
|
|
6083
|
+
await waitFor(() => rendered.getByText('Rendered Id: 99'))
|
|
6084
|
+
await waitFor(() => rendered.getByText('Rendered Id: 2'))
|
|
6085
|
+
expect(spy).toHaveBeenCalledTimes(2) // called with undefined because id changed
|
|
6086
|
+
|
|
6087
|
+
spy.mockClear()
|
|
6088
|
+
fireEvent.click(rendered.getByRole('button', { name: /1/ }))
|
|
6089
|
+
await waitFor(() => rendered.getByText('Rendered Id: 1'))
|
|
6090
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
6091
|
+
|
|
6092
|
+
spy.mockClear()
|
|
6093
|
+
fireEvent.click(rendered.getByRole('button', { name: /2/ }))
|
|
6094
|
+
await waitFor(() => rendered.getByText('Rendered Id: 2'))
|
|
6095
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
6096
|
+
})
|
|
5996
6097
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useQuery } from '../useQuery'
|
|
2
2
|
import { queryOptions } from '../queryOptions'
|
|
3
|
-
import type { Expect, Equal } from './utils'
|
|
4
3
|
import { doNotExecute } from './utils'
|
|
4
|
+
import type { Equal, Expect } from './utils'
|
|
5
5
|
|
|
6
6
|
describe('initialData', () => {
|
|
7
7
|
describe('Config object overload', () => {
|
package/src/__tests__/utils.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
2
|
import { act, render } from '@testing-library/react'
|
|
3
|
-
import type { QueryClientConfig } from '..'
|
|
4
|
-
import { QueryClient, QueryClientProvider } from '..'
|
|
5
3
|
import * as utils from '@tanstack/query-core'
|
|
6
4
|
import { vi } from 'vitest'
|
|
5
|
+
import { QueryClient, QueryClientProvider } from '..'
|
|
6
|
+
import type { QueryClientConfig } from '..'
|
|
7
7
|
|
|
8
8
|
export function renderWithClient(
|
|
9
9
|
client: QueryClient,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
'use client'
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
import { shouldThrowError } from './utils'
|
|
2
4
|
import type {
|
|
3
5
|
DefaultedQueryObserverOptions,
|
|
4
6
|
Query,
|
|
@@ -7,8 +9,6 @@ import type {
|
|
|
7
9
|
ThrowOnError,
|
|
8
10
|
} from '@tanstack/query-core'
|
|
9
11
|
import type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'
|
|
10
|
-
import * as React from 'react'
|
|
11
|
-
import { shouldThrowError } from './utils'
|
|
12
12
|
|
|
13
13
|
export const ensurePreventErrorBoundaryRetry = <
|
|
14
14
|
TQueryFnData,
|
package/src/suspense.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/* istanbul ignore file */
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
|
+
DefaultError,
|
|
5
|
+
DefinedQueryObserverResult,
|
|
4
6
|
InfiniteQueryObserverOptions,
|
|
5
7
|
InfiniteQueryObserverResult,
|
|
8
|
+
MutateFunction,
|
|
9
|
+
MutationObserverOptions,
|
|
6
10
|
MutationObserverResult,
|
|
11
|
+
QueryKey,
|
|
7
12
|
QueryObserverOptions,
|
|
8
13
|
QueryObserverResult,
|
|
9
|
-
QueryKey,
|
|
10
|
-
MutationObserverOptions,
|
|
11
|
-
MutateFunction,
|
|
12
|
-
DefinedQueryObserverResult,
|
|
13
14
|
WithRequired,
|
|
14
|
-
DefaultError,
|
|
15
15
|
} from '@tanstack/query-core'
|
|
16
16
|
|
|
17
17
|
export interface UseBaseQueryOptions<
|
package/src/useBaseQuery.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import * as React from 'react'
|
|
3
3
|
|
|
4
|
-
import type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'
|
|
5
4
|
import { notifyManager } from '@tanstack/query-core'
|
|
6
5
|
import { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'
|
|
7
6
|
import { useQueryClient } from './QueryClientProvider'
|
|
8
|
-
import type { UseBaseQueryOptions } from './types'
|
|
9
7
|
import { useIsRestoring } from './isRestoring'
|
|
10
8
|
import {
|
|
11
9
|
ensurePreventErrorBoundaryRetry,
|
|
12
10
|
getHasError,
|
|
13
11
|
useClearResetErrorBoundary,
|
|
14
12
|
} from './errorBoundaryUtils'
|
|
15
|
-
import { ensureStaleTime,
|
|
13
|
+
import { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'
|
|
14
|
+
import type { UseBaseQueryOptions } from './types'
|
|
15
|
+
import type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'
|
|
16
16
|
|
|
17
17
|
export function useBaseQuery<
|
|
18
18
|
TQueryFnData,
|
package/src/useInfiniteQuery.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use client'
|
|
2
|
+
import { InfiniteQueryObserver } from '@tanstack/query-core'
|
|
3
|
+
import { useBaseQuery } from './useBaseQuery'
|
|
2
4
|
import type {
|
|
3
|
-
QueryObserver,
|
|
4
|
-
QueryKey,
|
|
5
|
-
QueryClient,
|
|
6
5
|
DefaultError,
|
|
7
6
|
InfiniteData,
|
|
7
|
+
QueryClient,
|
|
8
|
+
QueryKey,
|
|
9
|
+
QueryObserver,
|
|
8
10
|
} from '@tanstack/query-core'
|
|
9
|
-
import { InfiniteQueryObserver } from '@tanstack/query-core'
|
|
10
11
|
import type { UseInfiniteQueryOptions, UseInfiniteQueryResult } from './types'
|
|
11
|
-
import { useBaseQuery } from './useBaseQuery'
|
|
12
12
|
|
|
13
13
|
// HOOK
|
|
14
14
|
export function useInfiniteQuery<
|
package/src/useIsFetching.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import * as React from 'react'
|
|
3
|
-
import type { QueryClient, QueryFilters } from '@tanstack/query-core'
|
|
4
3
|
import { notifyManager } from '@tanstack/query-core'
|
|
5
4
|
|
|
6
5
|
import { useQueryClient } from './QueryClientProvider'
|
|
6
|
+
import type { QueryClient, QueryFilters } from '@tanstack/query-core'
|
|
7
7
|
|
|
8
8
|
export function useIsFetching(
|
|
9
9
|
filters?: QueryFilters,
|
package/src/useMutation.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import * as React from 'react'
|
|
3
|
-
import
|
|
4
|
-
import { notifyManager, MutationObserver } from '@tanstack/query-core'
|
|
3
|
+
import { MutationObserver, notifyManager } from '@tanstack/query-core'
|
|
5
4
|
import { useQueryClient } from './QueryClientProvider'
|
|
5
|
+
import { shouldThrowError } from './utils'
|
|
6
6
|
import type {
|
|
7
7
|
UseMutateFunction,
|
|
8
8
|
UseMutationOptions,
|
|
9
9
|
UseMutationResult,
|
|
10
10
|
} from './types'
|
|
11
|
-
import {
|
|
11
|
+
import type { DefaultError, QueryClient } from '@tanstack/query-core'
|
|
12
12
|
|
|
13
13
|
// HOOK
|
|
14
14
|
|
package/src/useMutationState.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import * as React from 'react'
|
|
3
3
|
|
|
4
|
+
import { notifyManager, replaceEqualDeep } from '@tanstack/query-core'
|
|
5
|
+
import { useQueryClient } from './QueryClientProvider'
|
|
4
6
|
import type {
|
|
5
|
-
|
|
6
|
-
QueryClient,
|
|
7
|
+
DefaultError,
|
|
7
8
|
Mutation,
|
|
8
9
|
MutationCache,
|
|
9
|
-
|
|
10
|
+
MutationFilters,
|
|
10
11
|
MutationState,
|
|
12
|
+
QueryClient,
|
|
11
13
|
} from '@tanstack/query-core'
|
|
12
|
-
import { notifyManager, replaceEqualDeep } from '@tanstack/query-core'
|
|
13
|
-
import { useQueryClient } from './QueryClientProvider'
|
|
14
14
|
|
|
15
15
|
export function useIsMutating(
|
|
16
16
|
filters?: MutationFilters,
|