@@ -766,114 +766,6 @@ describe('hooks tests', () => {
766766 expect ( res . data ! . amount ) . toBeGreaterThan ( originalAmount )
767767 } )
768768
769- test ( 'Infinite Query Hook getNextPage Trigger' , async ( ) => {
770- server . use (
771- http . get ( 'https://example.com/listItems' , ( { request } ) => {
772- const url = new URL ( request . url )
773- const pageString = url . searchParams . get ( 'page' )
774- const pageNum = parseInt ( pageString || '0' )
775-
776- const results = { title : `page ${ pageNum } ` , info : 'more name' }
777- return HttpResponse . json ( results )
778- } ) ,
779- )
780-
781- type Pokemon = {
782- id : string
783- name : string
784- }
785-
786- const pokemonApi = createApi ( {
787- baseQuery : fetchBaseQuery ( { baseUrl : 'https://pokeapi.co/api/v2/' } ) ,
788- endpoints : ( builder ) => ( {
789- getInfinitePokemon : builder . infiniteQuery < Pokemon [ ] , string , number > ( {
790- infiniteQueryOptions : {
791- initialPageParam : 0 ,
792- getNextPageParam : (
793- lastPage ,
794- allPages ,
795- lastPageParam ,
796- allPageParams ,
797- ) => lastPageParam + 1 ,
798- } ,
799- query ( pageParam ) {
800- return `https://example.com/listItems?page=${ pageParam } `
801- } ,
802- } ) ,
803- } ) ,
804- } )
805-
806- const storeRef = setupApiStore ( pokemonApi , undefined , {
807- withoutTestLifecycles : true ,
808- } )
809-
810- const checkNumQueries = ( count : number ) => {
811- const cacheEntries = Object . keys ( storeRef . store . getState ( ) . api . queries )
812- const queries = cacheEntries . length
813- console . log ( 'queries' , queries , storeRef . store . getState ( ) . api . queries )
814-
815- expect ( queries ) . toBe ( count )
816- }
817-
818- function PokemonList ( ) {
819- const { data, isFetching, isUninitialized, fetchNextPage } =
820- pokemonApi . endpoints . getInfinitePokemon . useInfiniteQuery ( 'a' , {
821- initialPageParam : 0 ,
822- getNextPageParam : (
823- lastPage ,
824- allPages ,
825- // Page param type should be `number`
826- lastPageParam ,
827- allPageParams ,
828- ) => lastPageParam + 1 ,
829- } )
830-
831- const handleClick = async ( ) => {
832- const promise = fetchNextPage ( )
833- const res = await promise
834- }
835-
836- return (
837- < div >
838- < div data-testid = "isUninitialized" > { String ( isUninitialized ) } </ div >
839- < div data-testid = "isFetching" > { String ( isFetching ) } </ div >
840- < div data-testid = "data" >
841- { data ?. pages . map ( ( page : any , i : number | null | undefined ) => (
842- < div key = { i } > { JSON . stringify ( page ) } </ div >
843- ) ) }
844- </ div >
845- < button data-testid = "nextPage" onClick = { ( ) => handleClick ( ) } >
846- nextPage
847- </ button >
848- </ div >
849- )
850- }
851-
852- render ( < PokemonList /> , { wrapper : storeRef . wrapper } )
853- expect ( screen . getByTestId ( 'data' ) . textContent ) . toBe ( '' )
854- checkNumQueries ( 1 )
855-
856- await waitFor ( ( ) =>
857- expect ( screen . getByTestId ( 'isUninitialized' ) . textContent ) . toBe ( 'false' ) ,
858- )
859- await waitFor ( ( ) =>
860- expect ( screen . getByTestId ( 'isFetching' ) . textContent ) . toBe ( 'false' ) ,
861- )
862- act ( ( ) => {
863- fireEvent . click ( screen . getByTestId ( 'nextPage' ) )
864- } )
865- await waitFor ( ( ) =>
866- expect ( screen . getByTestId ( 'isFetching' ) . textContent ) . toBe ( 'false' ) ,
867- )
868- checkNumQueries ( 1 )
869- await waitFor ( ( ) =>
870- expect ( screen . getByTestId ( 'isFetching' ) . textContent ) . toBe ( 'false' ) ,
871- )
872- expect ( screen . getByTestId ( 'data' ) . textContent ) . toBe (
873- '{"title":"page 0","info":"more name"}{"title":"page 1","info":"more name"}' ,
874- )
875- } )
876-
877769 // See https://github.com/reduxjs/redux-toolkit/issues/4267 - Memory leak in useQuery rapid query arg changes
878770 test ( 'Hook subscriptions are properly cleaned up when query is fulfilled/rejected' , async ( ) => {
879771 // This is imported already, but it seems to be causing issues with the test on certain matrixes
@@ -1588,6 +1480,124 @@ describe('hooks tests', () => {
15881480 } )
15891481 } )
15901482
1483+ describe ( 'useInfiniteQuery' , ( ) => {
1484+ type Pokemon = {
1485+ id : string
1486+ name : string
1487+ }
1488+
1489+ const pokemonApi = createApi ( {
1490+ baseQuery : fetchBaseQuery ( { baseUrl : 'https://pokeapi.co/api/v2/' } ) ,
1491+ endpoints : ( builder ) => ( {
1492+ getInfinitePokemon : builder . infiniteQuery < Pokemon , string , number > ( {
1493+ infiniteQueryOptions : {
1494+ initialPageParam : 0 ,
1495+ getNextPageParam : (
1496+ lastPage ,
1497+ allPages ,
1498+ lastPageParam ,
1499+ allPageParams ,
1500+ ) => lastPageParam + 1 ,
1501+ } ,
1502+ query ( pageParam ) {
1503+ return `https://example.com/listItems?page=${ pageParam } `
1504+ } ,
1505+ } ) ,
1506+ } ) ,
1507+ } )
1508+
1509+ function PokemonList ( {
1510+ initialPageParam = 0 ,
1511+ } : {
1512+ initialPageParam ?: number
1513+ } ) {
1514+ const { data, isFetching, isUninitialized, fetchNextPage } =
1515+ pokemonApi . endpoints . getInfinitePokemon . useInfiniteQuery ( 'a' , {
1516+ initialPageParam,
1517+ getNextPageParam : (
1518+ lastPage ,
1519+ allPages ,
1520+ // Page param type should be `number`
1521+ lastPageParam ,
1522+ allPageParams ,
1523+ ) => lastPageParam + 1 ,
1524+ } )
1525+
1526+ const handleClick = async ( ) => {
1527+ const promise = fetchNextPage ( )
1528+ const res = await promise
1529+ }
1530+
1531+ return (
1532+ < div >
1533+ < div data-testid = "isUninitialized" > { String ( isUninitialized ) } </ div >
1534+ < div data-testid = "isFetching" > { String ( isFetching ) } </ div >
1535+ < div data-testid = "data" >
1536+ { data ?. pages . map ( ( page : any , i : number | null | undefined ) => (
1537+ < div key = { i } > { JSON . stringify ( page ) } </ div >
1538+ ) ) }
1539+ </ div >
1540+ < button data-testid = "nextPage" onClick = { ( ) => handleClick ( ) } >
1541+ nextPage
1542+ </ button >
1543+ </ div >
1544+ )
1545+ }
1546+
1547+ server . use (
1548+ http . get ( 'https://example.com/listItems' , ( { request } ) => {
1549+ const url = new URL ( request . url )
1550+ const pageString = url . searchParams . get ( 'page' )
1551+ const pageNum = parseInt ( pageString || '0' )
1552+
1553+ const results : Pokemon = {
1554+ id : `${ pageNum } ` ,
1555+ name : `Pokemon ${ pageNum } ` ,
1556+ }
1557+
1558+ return HttpResponse . json ( results )
1559+ } ) ,
1560+ )
1561+
1562+ test ( 'useInfiniteQuery fetchNextPage Trigger' , async ( ) => {
1563+ const storeRef = setupApiStore ( pokemonApi , undefined , {
1564+ withoutTestLifecycles : true ,
1565+ } )
1566+
1567+ const checkNumQueries = ( count : number ) => {
1568+ const cacheEntries = Object . keys ( storeRef . store . getState ( ) . api . queries )
1569+ const queries = cacheEntries . length
1570+ console . log ( 'queries' , queries , storeRef . store . getState ( ) . api . queries )
1571+
1572+ expect ( queries ) . toBe ( count )
1573+ }
1574+
1575+ render ( < PokemonList /> , { wrapper : storeRef . wrapper } )
1576+ expect ( screen . getByTestId ( 'data' ) . textContent ) . toBe ( '' )
1577+ checkNumQueries ( 1 )
1578+
1579+ await waitFor ( ( ) =>
1580+ expect ( screen . getByTestId ( 'isUninitialized' ) . textContent ) . toBe ( 'false' ) ,
1581+ )
1582+ await waitFor ( ( ) =>
1583+ expect ( screen . getByTestId ( 'isFetching' ) . textContent ) . toBe ( 'false' ) ,
1584+ )
1585+ act ( ( ) => {
1586+ fireEvent . click ( screen . getByTestId ( 'nextPage' ) )
1587+ } )
1588+ await waitFor ( ( ) =>
1589+ expect ( screen . getByTestId ( 'isFetching' ) . textContent ) . toBe ( 'false' ) ,
1590+ )
1591+ checkNumQueries ( 1 )
1592+ await waitFor ( ( ) =>
1593+ expect ( screen . getByTestId ( 'isFetching' ) . textContent ) . toBe ( 'false' ) ,
1594+ )
1595+ expect ( screen . getByTestId ( 'data' ) . textContent ) . toBe (
1596+ '{"id":"0","name":"Pokemon 0"}{"id":"1","name":"Pokemon 1"}' ,
1597+ )
1598+ } )
1599+ } )
1600+
15911601 describe ( 'useMutation' , ( ) => {
15921602 test ( 'useMutation hook sets and unsets the isLoading flag when running' , async ( ) => {
15931603 function User ( ) {
0 commit comments