@@ -914,17 +914,19 @@ describe('useQuery', () => {
914
914
// required to make sure no additional renders are happening after data is successfully fetched for the second time
915
915
await sleep ( 100 )
916
916
917
- expect ( states . length ) . toBe ( 5 )
917
+ expect ( states . length ) . toBe ( 4 )
918
918
// First load
919
919
expect ( states [ 0 ] ) . toMatchObject ( { isLoading : true , isSuccess : false } )
920
920
// First success
921
921
expect ( states [ 1 ] ) . toMatchObject ( { isLoading : false , isSuccess : true } )
922
922
// Remove
923
923
expect ( states [ 2 ] ) . toMatchObject ( { isLoading : true , isSuccess : false } )
924
924
// Hook state update
925
- expect ( states [ 3 ] ) . toMatchObject ( { isLoading : true , isSuccess : false } )
925
+ // this update is now skipped ! because nothing changed
926
+ // see github issue: https://github.com/TanStack/query/issues/5538
927
+ // expect(states[3]).toMatchObject({ isLoading: true, isSuccess: false })
926
928
// Second success
927
- expect ( states [ 4 ] ) . toMatchObject ( { isLoading : false , isSuccess : true } )
929
+ expect ( states [ 3 ] ) . toMatchObject ( { isLoading : false , isSuccess : true } )
928
930
} )
929
931
930
932
it ( 'should fetch when refetchOnMount is false and nothing has been fetched yet' , async ( ) => {
@@ -3650,6 +3652,7 @@ describe('useQuery', () => {
3650
3652
)
3651
3653
act ( ( ) => setPrefetched ( true ) )
3652
3654
}
3655
+
3653
3656
prefetch ( )
3654
3657
} , [ ] )
3655
3658
@@ -5879,6 +5882,7 @@ describe('useQuery', () => {
5879
5882
</ div >
5880
5883
)
5881
5884
}
5885
+
5882
5886
const rendered = renderWithClient ( queryClient , < Page /> )
5883
5887
const fetchBtn = rendered . getByRole ( 'button' , { name : 'refetch' } )
5884
5888
await waitFor ( ( ) => rendered . getByText ( 'data: 1' ) )
@@ -5916,8 +5920,84 @@ describe('useQuery', () => {
5916
5920
</ div >
5917
5921
)
5918
5922
}
5923
+
5919
5924
const rendered = renderWithClient ( queryClient , < Page /> )
5920
5925
await waitFor ( ( ) => rendered . getByText ( 'status: success' ) )
5921
5926
await waitFor ( ( ) => rendered . getByText ( 'data: 1' ) )
5922
5927
} )
5928
+ it ( 'should reuse same data object reference when queryKey changes back to some cached data' , async ( ) => {
5929
+ jest . useFakeTimers ( )
5930
+ const spy = jest . fn ( )
5931
+
5932
+ function fetchNumber ( id : number ) {
5933
+ return new Promise ( ( resolve ) => {
5934
+ setTimeout (
5935
+ ( ) =>
5936
+ resolve ( {
5937
+ numbers : {
5938
+ current : {
5939
+ id,
5940
+ } ,
5941
+ } ,
5942
+ } ) ,
5943
+ 1000 ,
5944
+ )
5945
+ } )
5946
+ }
5947
+ function Test ( ) {
5948
+ const [ id , setId ] = React . useState ( 1 )
5949
+
5950
+ const { data } = useQuery ( {
5951
+ select : selector ,
5952
+ queryKey : [ 'user' , id ] ,
5953
+ queryFn : ( ) => fetchNumber ( id ) ,
5954
+ } )
5955
+
5956
+ React . useEffect ( ( ) => {
5957
+ spy ( data )
5958
+ } , [ data ] )
5959
+
5960
+ return (
5961
+ < div >
5962
+ < button name = "1" onClick = { ( ) => setId ( 1 ) } >
5963
+ 1
5964
+ </ button >
5965
+ < button name = "2" onClick = { ( ) => setId ( 2 ) } >
5966
+ 2
5967
+ </ button >
5968
+ < span > Rendered Id: { data ?. id } </ span >
5969
+ </ div >
5970
+ )
5971
+ }
5972
+
5973
+ function selector ( data : any ) {
5974
+ return data . numbers . current
5975
+ }
5976
+
5977
+ const rendered = renderWithClient ( queryClient , < Test /> )
5978
+ expect ( spy ) . toHaveBeenCalledTimes ( 1 )
5979
+ spy . mockClear ( )
5980
+ jest . advanceTimersByTime ( 1000 )
5981
+ await waitFor ( ( ) => rendered . getByText ( 'Rendered Id: 1' ) )
5982
+ expect ( spy ) . toHaveBeenCalledTimes ( 1 )
5983
+ spy . mockClear ( )
5984
+
5985
+ fireEvent . click ( rendered . getByRole ( 'button' , { name : / 2 / } ) )
5986
+ jest . advanceTimersByTime ( 1000 )
5987
+ await waitFor ( ( ) => rendered . getByText ( 'Rendered Id: 2' ) )
5988
+ expect ( spy ) . toHaveBeenCalledTimes ( 2 ) // called with undefined because id changed
5989
+ spy . mockClear ( )
5990
+
5991
+ fireEvent . click ( rendered . getByRole ( 'button' , { name : / 1 / } ) )
5992
+ jest . advanceTimersByTime ( 1000 )
5993
+ await waitFor ( ( ) => rendered . getByText ( 'Rendered Id: 1' ) )
5994
+ expect ( spy ) . toHaveBeenCalledTimes ( 1 )
5995
+ spy . mockClear ( )
5996
+
5997
+ fireEvent . click ( rendered . getByRole ( 'button' , { name : / 2 / } ) )
5998
+ jest . advanceTimersByTime ( 1000 )
5999
+ await waitFor ( ( ) => rendered . getByText ( 'Rendered Id: 2' ) )
6000
+ expect ( spy ) . toHaveBeenCalledTimes ( 1 )
6001
+ spy . mockClear ( )
6002
+ } )
5923
6003
} )
0 commit comments