@@ -4102,6 +4102,56 @@ describe('useQuery', () => {
41024102 expect ( selectRun ) . toBe ( 3 )
41034103 } )
41044104
4105+ it ( 'select should always return the correct state' , async ( ) => {
4106+ const key1 = queryKey ( )
4107+
4108+ function Page ( ) {
4109+ const [ count , inc ] = React . useReducer ( prev => prev + 1 , 2 )
4110+ const [ forceValue , forceUpdate ] = React . useReducer ( prev => prev + 1 , 1 )
4111+
4112+ const state = useQuery (
4113+ key1 ,
4114+ async ( ) => {
4115+ await sleep ( 10 )
4116+ return 0
4117+ } ,
4118+ {
4119+ select : React . useCallback (
4120+ ( data : number ) => {
4121+ return `selected ${ data + count } `
4122+ } ,
4123+ [ count ]
4124+ ) ,
4125+ placeholderData : 99 ,
4126+ }
4127+ )
4128+
4129+ return (
4130+ < div >
4131+ < h2 > Data: { state . data } </ h2 >
4132+ < h2 > forceValue: { forceValue } </ h2 >
4133+ < button onClick = { inc } > inc: { count } </ button >
4134+ < button onClick = { forceUpdate } > forceUpdate</ button >
4135+ </ div >
4136+ )
4137+ }
4138+
4139+ const rendered = renderWithClient ( queryClient , < Page /> )
4140+ await waitFor ( ( ) => rendered . getByText ( 'Data: selected 101' ) ) // 99 + 2
4141+
4142+ await waitFor ( ( ) => rendered . getByText ( 'Data: selected 2' ) ) // 0 + 2
4143+
4144+ rendered . getByRole ( 'button' , { name : / i n c / i } ) . click ( )
4145+
4146+ await waitFor ( ( ) => rendered . getByText ( 'Data: selected 3' ) ) // 0 + 3
4147+
4148+ rendered . getByRole ( 'button' , { name : / f o r c e U p d a t e / i } ) . click ( )
4149+
4150+ await waitFor ( ( ) => rendered . getByText ( 'forceValue: 2' ) )
4151+ // data should still be 3 after an independent re-render
4152+ await waitFor ( ( ) => rendered . getByText ( 'Data: selected 3' ) )
4153+ } )
4154+
41054155 it ( 'should cancel the query function when there are no more subscriptions' , async ( ) => {
41064156 const key = queryKey ( )
41074157 let cancelFn : jest . Mock = jest . fn ( )
@@ -4611,6 +4661,82 @@ describe('useQuery', () => {
46114661 consoleMock . mockRestore ( )
46124662 } )
46134663
4664+ it ( 'should have no error in loading state when refetching after error occurred' , async ( ) => {
4665+ const consoleMock = mockConsoleError ( )
4666+ const key = queryKey ( )
4667+ const states : UseQueryResult < number > [ ] = [ ]
4668+ const error = new Error ( 'oops' )
4669+
4670+ let count = 0
4671+
4672+ function Page ( ) {
4673+ const state = useQuery (
4674+ key ,
4675+ async ( ) => {
4676+ await sleep ( 10 )
4677+ if ( count === 0 ) {
4678+ count ++
4679+ throw error
4680+ }
4681+ return 5
4682+ } ,
4683+ {
4684+ retry : false ,
4685+ }
4686+ )
4687+
4688+ states . push ( state )
4689+
4690+ if ( state . isLoading ) {
4691+ return < div > status: loading</ div >
4692+ }
4693+ if ( state . error instanceof Error ) {
4694+ return (
4695+ < div >
4696+ < div > error</ div >
4697+ < button onClick = { ( ) => state . refetch ( ) } > refetch</ button >
4698+ </ div >
4699+ )
4700+ }
4701+ return < div > data: { state . data } </ div >
4702+ }
4703+
4704+ const rendered = renderWithClient ( queryClient , < Page /> )
4705+
4706+ await waitFor ( ( ) => rendered . getByText ( 'error' ) )
4707+
4708+ fireEvent . click ( rendered . getByRole ( 'button' , { name : 'refetch' } ) )
4709+ await waitFor ( ( ) => rendered . getByText ( 'data: 5' ) )
4710+
4711+ await waitFor ( ( ) => expect ( states . length ) . toBe ( 4 ) )
4712+
4713+ expect ( states [ 0 ] ) . toMatchObject ( {
4714+ status : 'loading' ,
4715+ data : undefined ,
4716+ error : null ,
4717+ } )
4718+
4719+ expect ( states [ 1 ] ) . toMatchObject ( {
4720+ status : 'error' ,
4721+ data : undefined ,
4722+ error,
4723+ } )
4724+
4725+ expect ( states [ 2 ] ) . toMatchObject ( {
4726+ status : 'loading' ,
4727+ data : undefined ,
4728+ error : null ,
4729+ } )
4730+
4731+ expect ( states [ 3 ] ) . toMatchObject ( {
4732+ status : 'success' ,
4733+ data : 5 ,
4734+ error : null ,
4735+ } )
4736+
4737+ consoleMock . mockRestore ( )
4738+ } )
4739+
46144740 describe ( 'networkMode online' , ( ) => {
46154741 it ( 'online queries should not start fetching if you are offline' , async ( ) => {
46164742 const onlineMock = mockNavigatorOnLine ( false )
0 commit comments