@tanstack/react-query 4.14.1 → 4.14.5
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/umd/index.development.js +22 -13
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/useInfiniteQuery.test.tsx +36 -10
- package/src/__tests__/useQuery.test.tsx +70 -75
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/react-query",
|
|
3
|
-
"version": "4.14.
|
|
3
|
+
"version": "4.14.5",
|
|
4
4
|
"description": "Hooks for managing, caching and syncing asynchronous and remote data in React",
|
|
5
5
|
"author": "tannerlinsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"react-error-boundary": "^3.1.4"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@tanstack/query-core": "4.14.
|
|
49
|
+
"@tanstack/query-core": "4.14.5",
|
|
50
50
|
"use-sync-external-store": "^1.2.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
@@ -2,7 +2,6 @@ import { fireEvent, waitFor } from '@testing-library/react'
|
|
|
2
2
|
import * as React from 'react'
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
|
-
Blink,
|
|
6
5
|
createQueryClient,
|
|
7
6
|
queryKey,
|
|
8
7
|
renderWithClient,
|
|
@@ -517,24 +516,28 @@ describe('useInfiniteQuery', () => {
|
|
|
517
516
|
data: undefined,
|
|
518
517
|
isFetching: true,
|
|
519
518
|
isFetchingNextPage: false,
|
|
519
|
+
isRefetching: false,
|
|
520
520
|
})
|
|
521
521
|
// Initial fetch done
|
|
522
522
|
expect(states[1]).toMatchObject({
|
|
523
523
|
data: { pages: [10] },
|
|
524
524
|
isFetching: false,
|
|
525
525
|
isFetchingNextPage: false,
|
|
526
|
+
isRefetching: false,
|
|
526
527
|
})
|
|
527
528
|
// Fetch next page
|
|
528
529
|
expect(states[2]).toMatchObject({
|
|
529
530
|
data: { pages: [10] },
|
|
530
531
|
isFetching: true,
|
|
531
532
|
isFetchingNextPage: true,
|
|
533
|
+
isRefetching: false,
|
|
532
534
|
})
|
|
533
535
|
// Fetch next page done
|
|
534
536
|
expect(states[3]).toMatchObject({
|
|
535
537
|
data: { pages: [10, 11] },
|
|
536
538
|
isFetching: false,
|
|
537
539
|
isFetchingNextPage: false,
|
|
540
|
+
isRefetching: false,
|
|
538
541
|
})
|
|
539
542
|
// Fetch previous page
|
|
540
543
|
expect(states[4]).toMatchObject({
|
|
@@ -542,6 +545,7 @@ describe('useInfiniteQuery', () => {
|
|
|
542
545
|
isFetching: true,
|
|
543
546
|
isFetchingNextPage: false,
|
|
544
547
|
isFetchingPreviousPage: true,
|
|
548
|
+
isRefetching: false,
|
|
545
549
|
})
|
|
546
550
|
// Fetch previous page done
|
|
547
551
|
expect(states[5]).toMatchObject({
|
|
@@ -549,6 +553,7 @@ describe('useInfiniteQuery', () => {
|
|
|
549
553
|
isFetching: false,
|
|
550
554
|
isFetchingNextPage: false,
|
|
551
555
|
isFetchingPreviousPage: false,
|
|
556
|
+
isRefetching: false,
|
|
552
557
|
})
|
|
553
558
|
// Refetch
|
|
554
559
|
expect(states[6]).toMatchObject({
|
|
@@ -556,6 +561,7 @@ describe('useInfiniteQuery', () => {
|
|
|
556
561
|
isFetching: true,
|
|
557
562
|
isFetchingNextPage: false,
|
|
558
563
|
isFetchingPreviousPage: false,
|
|
564
|
+
isRefetching: true,
|
|
559
565
|
})
|
|
560
566
|
// Refetch done
|
|
561
567
|
expect(states[7]).toMatchObject({
|
|
@@ -563,6 +569,7 @@ describe('useInfiniteQuery', () => {
|
|
|
563
569
|
isFetching: false,
|
|
564
570
|
isFetchingNextPage: false,
|
|
565
571
|
isFetchingPreviousPage: false,
|
|
572
|
+
isRefetching: false,
|
|
566
573
|
})
|
|
567
574
|
})
|
|
568
575
|
|
|
@@ -619,24 +626,28 @@ describe('useInfiniteQuery', () => {
|
|
|
619
626
|
data: undefined,
|
|
620
627
|
isFetching: true,
|
|
621
628
|
isFetchingNextPage: false,
|
|
629
|
+
isRefetching: false,
|
|
622
630
|
})
|
|
623
631
|
// Initial fetch done
|
|
624
632
|
expect(states[1]).toMatchObject({
|
|
625
633
|
data: { pages: [10] },
|
|
626
634
|
isFetching: false,
|
|
627
635
|
isFetchingNextPage: false,
|
|
636
|
+
isRefetching: false,
|
|
628
637
|
})
|
|
629
638
|
// Fetch next page
|
|
630
639
|
expect(states[2]).toMatchObject({
|
|
631
640
|
data: { pages: [10] },
|
|
632
641
|
isFetching: true,
|
|
633
642
|
isFetchingNextPage: true,
|
|
643
|
+
isRefetching: false,
|
|
634
644
|
})
|
|
635
645
|
// Fetch next page done
|
|
636
646
|
expect(states[3]).toMatchObject({
|
|
637
647
|
data: { pages: [10, 11] },
|
|
638
648
|
isFetching: false,
|
|
639
649
|
isFetchingNextPage: false,
|
|
650
|
+
isRefetching: false,
|
|
640
651
|
})
|
|
641
652
|
// Fetch previous page
|
|
642
653
|
expect(states[4]).toMatchObject({
|
|
@@ -644,6 +655,7 @@ describe('useInfiniteQuery', () => {
|
|
|
644
655
|
isFetching: true,
|
|
645
656
|
isFetchingNextPage: false,
|
|
646
657
|
isFetchingPreviousPage: true,
|
|
658
|
+
isRefetching: false,
|
|
647
659
|
})
|
|
648
660
|
// Fetch previous page done
|
|
649
661
|
expect(states[5]).toMatchObject({
|
|
@@ -651,6 +663,7 @@ describe('useInfiniteQuery', () => {
|
|
|
651
663
|
isFetching: false,
|
|
652
664
|
isFetchingNextPage: false,
|
|
653
665
|
isFetchingPreviousPage: false,
|
|
666
|
+
isRefetching: false,
|
|
654
667
|
})
|
|
655
668
|
// Refetch
|
|
656
669
|
expect(states[6]).toMatchObject({
|
|
@@ -658,6 +671,7 @@ describe('useInfiniteQuery', () => {
|
|
|
658
671
|
isFetching: true,
|
|
659
672
|
isFetchingNextPage: false,
|
|
660
673
|
isFetchingPreviousPage: false,
|
|
674
|
+
isRefetching: true,
|
|
661
675
|
})
|
|
662
676
|
// Refetch done
|
|
663
677
|
expect(states[7]).toMatchObject({
|
|
@@ -665,6 +679,7 @@ describe('useInfiniteQuery', () => {
|
|
|
665
679
|
isFetching: false,
|
|
666
680
|
isFetchingNextPage: false,
|
|
667
681
|
isFetchingPreviousPage: false,
|
|
682
|
+
isRefetching: false,
|
|
668
683
|
})
|
|
669
684
|
})
|
|
670
685
|
|
|
@@ -1725,13 +1740,13 @@ describe('useInfiniteQuery', () => {
|
|
|
1725
1740
|
const promise = new Promise<string>((resolve, reject) => {
|
|
1726
1741
|
cancelFn = jest.fn(() => reject('Cancelled'))
|
|
1727
1742
|
signal?.addEventListener('abort', cancelFn)
|
|
1728
|
-
sleep(
|
|
1743
|
+
sleep(1000).then(() => resolve('OK'))
|
|
1729
1744
|
})
|
|
1730
1745
|
|
|
1731
1746
|
return promise
|
|
1732
1747
|
}
|
|
1733
1748
|
|
|
1734
|
-
function
|
|
1749
|
+
function Inner() {
|
|
1735
1750
|
const state = useInfiniteQuery(key, queryFn)
|
|
1736
1751
|
return (
|
|
1737
1752
|
<div>
|
|
@@ -1740,14 +1755,25 @@ describe('useInfiniteQuery', () => {
|
|
|
1740
1755
|
)
|
|
1741
1756
|
}
|
|
1742
1757
|
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1758
|
+
function Page() {
|
|
1759
|
+
const [isVisible, setIsVisible] = React.useState(true)
|
|
1760
|
+
|
|
1761
|
+
return (
|
|
1762
|
+
<>
|
|
1763
|
+
<button onClick={() => setIsVisible(false)}>hide</button>
|
|
1764
|
+
{isVisible && <Inner />}
|
|
1765
|
+
<div>{isVisible ? 'visible' : 'hidden'}</div>
|
|
1766
|
+
</>
|
|
1767
|
+
)
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
const rendered = renderWithClient(queryClient, <Page />)
|
|
1771
|
+
|
|
1772
|
+
await waitFor(() => rendered.getByText('visible'))
|
|
1773
|
+
|
|
1774
|
+
fireEvent.click(rendered.getByRole('button', { name: 'hide' }))
|
|
1749
1775
|
|
|
1750
|
-
await waitFor(() => rendered.getByText('
|
|
1776
|
+
await waitFor(() => rendered.getByText('hidden'))
|
|
1751
1777
|
|
|
1752
1778
|
expect(cancelFn).toHaveBeenCalled()
|
|
1753
1779
|
})
|
|
@@ -969,12 +969,15 @@ describe('useQuery', () => {
|
|
|
969
969
|
select: (data) => data.name,
|
|
970
970
|
})
|
|
971
971
|
states.push(state)
|
|
972
|
-
|
|
972
|
+
|
|
973
|
+
return <div>{state.data}</div>
|
|
973
974
|
}
|
|
974
975
|
|
|
975
|
-
renderWithClient(queryClient, <Page />)
|
|
976
|
+
const rendered = renderWithClient(queryClient, <Page />)
|
|
976
977
|
|
|
977
|
-
await
|
|
978
|
+
await waitFor(() => {
|
|
979
|
+
rendered.getByText('test')
|
|
980
|
+
})
|
|
978
981
|
|
|
979
982
|
expect(states.length).toBe(2)
|
|
980
983
|
expect(states[0]).toMatchObject({ data: undefined })
|
|
@@ -992,12 +995,15 @@ describe('useQuery', () => {
|
|
|
992
995
|
select: (data) => data.name,
|
|
993
996
|
})
|
|
994
997
|
states.push(state)
|
|
995
|
-
|
|
998
|
+
|
|
999
|
+
return <div>{state.data}</div>
|
|
996
1000
|
}
|
|
997
1001
|
|
|
998
|
-
renderWithClient(queryClient, <Page />)
|
|
1002
|
+
const rendered = renderWithClient(queryClient, <Page />)
|
|
999
1003
|
|
|
1000
|
-
await
|
|
1004
|
+
await waitFor(() => {
|
|
1005
|
+
rendered.getByText('test')
|
|
1006
|
+
})
|
|
1001
1007
|
|
|
1002
1008
|
expect(states.length).toBe(2)
|
|
1003
1009
|
expect(states[0]).toMatchObject({ data: undefined })
|
|
@@ -1016,24 +1022,32 @@ describe('useQuery', () => {
|
|
|
1016
1022
|
|
|
1017
1023
|
states.push(state)
|
|
1018
1024
|
|
|
1019
|
-
|
|
1025
|
+
return (
|
|
1026
|
+
<div>
|
|
1027
|
+
<div>{state?.data}</div>
|
|
1028
|
+
<button onClick={() => state.refetch()}>refetch</button>
|
|
1029
|
+
</div>
|
|
1030
|
+
)
|
|
1031
|
+
}
|
|
1020
1032
|
|
|
1021
|
-
|
|
1022
|
-
setActTimeout(() => {
|
|
1023
|
-
refetch()
|
|
1024
|
-
}, 5)
|
|
1025
|
-
}, [refetch])
|
|
1033
|
+
const rendered = renderWithClient(queryClient, <Page />)
|
|
1026
1034
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1035
|
+
await waitFor(() => {
|
|
1036
|
+
rendered.getByText('test')
|
|
1037
|
+
})
|
|
1029
1038
|
|
|
1030
|
-
|
|
1039
|
+
fireEvent.click(rendered.getByRole('button', { name: 'refetch' }))
|
|
1031
1040
|
|
|
1032
|
-
await
|
|
1041
|
+
await waitFor(() => {
|
|
1042
|
+
rendered.getByText('test')
|
|
1043
|
+
})
|
|
1033
1044
|
|
|
1034
|
-
expect(states.length).toBe(2)
|
|
1035
1045
|
expect(states[0]).toMatchObject({ data: undefined })
|
|
1036
1046
|
expect(states[1]).toMatchObject({ data: 'test' })
|
|
1047
|
+
|
|
1048
|
+
// make sure no additional renders happen
|
|
1049
|
+
await sleep(50)
|
|
1050
|
+
expect(states.length).toBe(2)
|
|
1037
1051
|
})
|
|
1038
1052
|
|
|
1039
1053
|
it('should throw an error when a selector throws', async () => {
|
|
@@ -1596,18 +1610,21 @@ describe('useQuery', () => {
|
|
|
1596
1610
|
|
|
1597
1611
|
states.push(state)
|
|
1598
1612
|
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
return null
|
|
1613
|
+
return (
|
|
1614
|
+
<div>
|
|
1615
|
+
<div>data: {state.data}</div>
|
|
1616
|
+
<button onClick={() => setCount(1)}>setCount</button>
|
|
1617
|
+
</div>
|
|
1618
|
+
)
|
|
1606
1619
|
}
|
|
1607
1620
|
|
|
1608
|
-
renderWithClient(queryClient, <Page />)
|
|
1621
|
+
const rendered = renderWithClient(queryClient, <Page />)
|
|
1622
|
+
|
|
1623
|
+
await waitFor(() => rendered.getByText('data: 0'))
|
|
1609
1624
|
|
|
1610
|
-
|
|
1625
|
+
fireEvent.click(rendered.getByRole('button', { name: 'setCount' }))
|
|
1626
|
+
|
|
1627
|
+
await waitFor(() => rendered.getByText('data: 1'))
|
|
1611
1628
|
|
|
1612
1629
|
// Initial
|
|
1613
1630
|
expect(states[0]).toMatchObject({
|
|
@@ -1630,15 +1647,8 @@ describe('useQuery', () => {
|
|
|
1630
1647
|
isSuccess: true,
|
|
1631
1648
|
isPreviousData: true,
|
|
1632
1649
|
})
|
|
1633
|
-
// Hook state update
|
|
1634
|
-
expect(states[3]).toMatchObject({
|
|
1635
|
-
data: 0,
|
|
1636
|
-
isFetching: true,
|
|
1637
|
-
isSuccess: true,
|
|
1638
|
-
isPreviousData: true,
|
|
1639
|
-
})
|
|
1640
1650
|
// New data
|
|
1641
|
-
expect(states[
|
|
1651
|
+
expect(states[3]).toMatchObject({
|
|
1642
1652
|
data: 1,
|
|
1643
1653
|
isFetching: false,
|
|
1644
1654
|
isSuccess: true,
|
|
@@ -2196,38 +2206,6 @@ describe('useQuery', () => {
|
|
|
2196
2206
|
expect(states[2]).toMatchObject({ isStale: true })
|
|
2197
2207
|
})
|
|
2198
2208
|
|
|
2199
|
-
it('should notify query cache when a query becomes stale', async () => {
|
|
2200
|
-
const key = queryKey()
|
|
2201
|
-
const states: UseQueryResult<string>[] = []
|
|
2202
|
-
const fn = jest.fn()
|
|
2203
|
-
|
|
2204
|
-
const unsubscribe = queryCache.subscribe(fn)
|
|
2205
|
-
|
|
2206
|
-
function Page() {
|
|
2207
|
-
const state = useQuery(key, () => 'test', {
|
|
2208
|
-
staleTime: 10,
|
|
2209
|
-
})
|
|
2210
|
-
states.push(state)
|
|
2211
|
-
return null
|
|
2212
|
-
}
|
|
2213
|
-
|
|
2214
|
-
renderWithClient(queryClient, <Page />)
|
|
2215
|
-
|
|
2216
|
-
await sleep(20)
|
|
2217
|
-
unsubscribe()
|
|
2218
|
-
|
|
2219
|
-
// 1. Query added -> loading
|
|
2220
|
-
// 2. Observer result updated -> loading
|
|
2221
|
-
// 3. Observer added
|
|
2222
|
-
// 4. Query updated -> success
|
|
2223
|
-
// 5. Observer result updated -> success
|
|
2224
|
-
// 6. Query updated -> stale
|
|
2225
|
-
// 7. Observer options updated
|
|
2226
|
-
// 8. Observer result updated -> stale
|
|
2227
|
-
// 9. Observer options updated
|
|
2228
|
-
expect(fn).toHaveBeenCalledTimes(9)
|
|
2229
|
-
})
|
|
2230
|
-
|
|
2231
2209
|
it('should not re-render when it should only re-render on data changes and the data did not change', async () => {
|
|
2232
2210
|
const key = queryKey()
|
|
2233
2211
|
const states: UseQueryResult<string>[] = []
|
|
@@ -3815,18 +3793,35 @@ describe('useQuery', () => {
|
|
|
3815
3793
|
|
|
3816
3794
|
results.push(result)
|
|
3817
3795
|
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3796
|
+
return (
|
|
3797
|
+
<div>
|
|
3798
|
+
<div>{result.data}</div>
|
|
3799
|
+
<div>{shouldFetch ? 'enabled' : 'disabled'}</div>
|
|
3800
|
+
<button
|
|
3801
|
+
onClick={() => {
|
|
3802
|
+
setShouldFetch(false)
|
|
3803
|
+
}}
|
|
3804
|
+
>
|
|
3805
|
+
enable
|
|
3806
|
+
</button>
|
|
3807
|
+
</div>
|
|
3808
|
+
)
|
|
3825
3809
|
}
|
|
3826
3810
|
|
|
3827
|
-
renderWithClient(queryClient, <Page />)
|
|
3811
|
+
const rendered = renderWithClient(queryClient, <Page />)
|
|
3812
|
+
|
|
3813
|
+
await waitFor(() => {
|
|
3814
|
+
rendered.getByText('fetched data')
|
|
3815
|
+
rendered.getByText('enabled')
|
|
3816
|
+
})
|
|
3817
|
+
|
|
3818
|
+
fireEvent.click(rendered.getByRole('button', { name: /enable/i }))
|
|
3819
|
+
|
|
3820
|
+
await waitFor(() => {
|
|
3821
|
+
rendered.getByText('fetched data')
|
|
3822
|
+
rendered.getByText('disabled')
|
|
3823
|
+
})
|
|
3828
3824
|
|
|
3829
|
-
await sleep(50)
|
|
3830
3825
|
expect(results.length).toBe(3)
|
|
3831
3826
|
expect(results[0]).toMatchObject({ data: 'initial', isStale: true })
|
|
3832
3827
|
expect(results[1]).toMatchObject({ data: 'fetched data', isStale: true })
|