@@ -2711,6 +2711,111 @@ describe('useQuery', () => {
2711
2711
consoleMock . mockRestore ( )
2712
2712
} )
2713
2713
2714
+ it ( 'should continue retries when observers unmount and remount while waiting for a retry (#3031)' , async ( ) => {
2715
+ const key = queryKey ( )
2716
+ const consoleMock = mockConsoleError ( )
2717
+ let count = 0
2718
+
2719
+ function Page ( ) {
2720
+ const result = useQuery (
2721
+ key ,
2722
+ async ( ) => {
2723
+ count ++
2724
+ await sleep ( 10 )
2725
+ return Promise . reject ( 'some error' )
2726
+ } ,
2727
+ {
2728
+ retry : 2 ,
2729
+ retryDelay : 100 ,
2730
+ }
2731
+ )
2732
+
2733
+ return (
2734
+ < div >
2735
+ < div > error: { result . error ?? 'null' } </ div >
2736
+ < div > failureCount: { result . failureCount } </ div >
2737
+ </ div >
2738
+ )
2739
+ }
2740
+
2741
+ function App ( ) {
2742
+ const [ show , toggle ] = React . useReducer ( x => ! x , true )
2743
+
2744
+ return (
2745
+ < div >
2746
+ < button onClick = { toggle } > { show ? 'hide' : 'show' } </ button >
2747
+ { show && < Page /> }
2748
+ </ div >
2749
+ )
2750
+ }
2751
+
2752
+ const rendered = renderWithClient ( queryClient , < App /> )
2753
+
2754
+ await waitFor ( ( ) => rendered . getByText ( 'failureCount: 1' ) )
2755
+ rendered . getByRole ( 'button' , { name : / h i d e / i } ) . click ( )
2756
+ rendered . getByRole ( 'button' , { name : / s h o w / i } ) . click ( )
2757
+ await waitFor ( ( ) => rendered . getByText ( 'error: some error' ) )
2758
+
2759
+ expect ( count ) . toBe ( 3 )
2760
+
2761
+ consoleMock . mockRestore ( )
2762
+ } )
2763
+
2764
+ it ( 'should restart when observers unmount and remount while waiting for a retry when query was cancelled in between (#3031)' , async ( ) => {
2765
+ const key = queryKey ( )
2766
+ const consoleMock = mockConsoleError ( )
2767
+ let count = 0
2768
+
2769
+ function Page ( ) {
2770
+ const result = useQuery (
2771
+ key ,
2772
+ async ( ) => {
2773
+ count ++
2774
+ await sleep ( 10 )
2775
+ return Promise . reject ( 'some error' )
2776
+ } ,
2777
+ {
2778
+ retry : 2 ,
2779
+ retryDelay : 100 ,
2780
+ }
2781
+ )
2782
+
2783
+ return (
2784
+ < div >
2785
+ < div > error: { result . error ?? 'null' } </ div >
2786
+ < div > failureCount: { result . failureCount } </ div >
2787
+ </ div >
2788
+ )
2789
+ }
2790
+
2791
+ function App ( ) {
2792
+ const [ show , toggle ] = React . useReducer ( x => ! x , true )
2793
+
2794
+ return (
2795
+ < div >
2796
+ < button onClick = { toggle } > { show ? 'hide' : 'show' } </ button >
2797
+ < button onClick = { ( ) => queryClient . cancelQueries ( { queryKey : key } ) } >
2798
+ cancel
2799
+ </ button >
2800
+ { show && < Page /> }
2801
+ </ div >
2802
+ )
2803
+ }
2804
+
2805
+ const rendered = renderWithClient ( queryClient , < App /> )
2806
+
2807
+ await waitFor ( ( ) => rendered . getByText ( 'failureCount: 1' ) )
2808
+ rendered . getByRole ( 'button' , { name : / h i d e / i } ) . click ( )
2809
+ rendered . getByRole ( 'button' , { name : / c a n c e l / i } ) . click ( )
2810
+ rendered . getByRole ( 'button' , { name : / s h o w / i } ) . click ( )
2811
+ await waitFor ( ( ) => rendered . getByText ( 'error: some error' ) )
2812
+
2813
+ // initial fetch (1), which will be cancelled, followed by new mount(2) + 2 retries = 4
2814
+ expect ( count ) . toBe ( 4 )
2815
+
2816
+ consoleMock . mockRestore ( )
2817
+ } )
2818
+
2714
2819
it ( 'should always fetch if refetchOnMount is set to always' , async ( ) => {
2715
2820
const key = queryKey ( )
2716
2821
const states : UseQueryResult < string > [ ] = [ ]
0 commit comments