@@ -126,10 +126,10 @@ const api = createApi({
126126 } ,
127127 } ) ,
128128 queryWithDeepArg : build . query < string , { param : { nested : string } } > ( {
129- query : ( { param : { nested } } ) => nested ,
129+ query : ( { param : { nested } } ) => nested ,
130130 serializeQueryArgs : ( { queryArgs } ) => {
131131 return queryArgs . param . nested
132- }
132+ } ,
133133 } ) ,
134134 } ) ,
135135} )
@@ -383,6 +383,54 @@ describe('hooks tests', () => {
383383 expect ( fetchingHist ) . toEqual ( [ true , false , true , false ] )
384384 } )
385385
386+ test ( '`isSuccess` does not jump back false on subsequent queries' , async ( ) => {
387+ type LoadingState = {
388+ id : number
389+ isFetching : boolean
390+ isSuccess : boolean
391+ }
392+ const loadingHistory : LoadingState [ ] = [ ]
393+
394+ function User ( { id } : { id : number } ) {
395+ const queryRes = api . endpoints . getUser . useQuery ( id )
396+
397+ useEffect ( ( ) => {
398+ const { isFetching, isSuccess } = queryRes
399+ loadingHistory . push ( { id, isFetching, isSuccess } )
400+ } , [ id , queryRes ] )
401+ return (
402+ < div data-testid = "status" >
403+ { queryRes . status === QueryStatus . fulfilled && id }
404+ </ div >
405+ )
406+ }
407+
408+ let { rerender } = render ( < User id = { 1 } /> , { wrapper : storeRef . wrapper } )
409+
410+ await waitFor ( ( ) =>
411+ expect ( screen . getByTestId ( 'status' ) . textContent ) . toBe ( '1' ) ,
412+ )
413+ rerender ( < User id = { 2 } /> )
414+
415+ await waitFor ( ( ) =>
416+ expect ( screen . getByTestId ( 'status' ) . textContent ) . toBe ( '2' ) ,
417+ )
418+
419+ expect ( loadingHistory ) . toEqual ( [
420+ // Initial render(s)
421+ { id : 1 , isFetching : true , isSuccess : false } ,
422+ { id : 1 , isFetching : true , isSuccess : false } ,
423+ // Data returned
424+ { id : 1 , isFetching : false , isSuccess : true } ,
425+ // ID changed, there's an uninitialized cache entry.
426+ // IMPORTANT: `isSuccess` should not be false here.
427+ // We have valid data already for the old item.
428+ { id : 2 , isFetching : true , isSuccess : true } ,
429+ { id : 2 , isFetching : true , isSuccess : true } ,
430+ { id : 2 , isFetching : false , isSuccess : true } ,
431+ ] )
432+ } )
433+
386434 test ( 'useQuery hook respects refetchOnMountOrArgChange: true' , async ( ) => {
387435 let data , isLoading , isFetching
388436 function User ( ) {
@@ -674,9 +722,11 @@ describe('hooks tests', () => {
674722 } )
675723
676724 test ( `useQuery shouldn't call args serialization if request skipped` , async ( ) => {
677- expect ( ( ) => renderHook ( ( ) => api . endpoints . queryWithDeepArg . useQuery ( skipToken ) , {
678- wrapper : storeRef . wrapper ,
679- } ) ) . not . toThrow ( )
725+ expect ( ( ) =>
726+ renderHook ( ( ) => api . endpoints . queryWithDeepArg . useQuery ( skipToken ) , {
727+ wrapper : storeRef . wrapper ,
728+ } ) ,
729+ ) . not . toThrow ( )
680730 } )
681731
682732 test ( `useQuery gracefully handles bigint types` , async ( ) => {
@@ -2861,6 +2911,7 @@ describe('skip behavior', () => {
28612911 } )
28622912 expect ( result . current ) . toEqual ( {
28632913 ...uninitialized ,
2914+ isSuccess : true ,
28642915 currentData : undefined ,
28652916 data : { name : 'Timmy' } ,
28662917 } )
@@ -2898,6 +2949,7 @@ describe('skip behavior', () => {
28982949 } )
28992950 expect ( result . current ) . toEqual ( {
29002951 ...uninitialized ,
2952+ isSuccess : true ,
29012953 currentData : undefined ,
29022954 data : { name : 'Timmy' } ,
29032955 } )
@@ -2936,7 +2988,7 @@ describe('skip behavior', () => {
29362988 // even though it's skipped. `currentData` is undefined, since that matches the current arg.
29372989 expect ( result . current ) . toMatchObject ( {
29382990 status : QueryStatus . uninitialized ,
2939- isSuccess : false ,
2991+ isSuccess : true ,
29402992 data : { name : 'Timmy' } ,
29412993 currentData : undefined ,
29422994 } )
0 commit comments