File tree Expand file tree Collapse file tree 2 files changed +76
-21
lines changed Expand file tree Collapse file tree 2 files changed +76
-21
lines changed Original file line number Diff line number Diff line change @@ -232,32 +232,31 @@ export class Query<TResult, TError> {
232232 }
233233
234234 onWindowFocus ( ) : void {
235- if (
236- this . observers . some (
237- observer =>
238- observer . isStale ( ) &&
239- observer . config . enabled &&
240- observer . config . refetchOnWindowFocus
241- )
242- ) {
243- this . fetch ( ) . catch ( noop )
244- }
245-
246- this . continue ( )
235+ this . onInteraction ( true , false )
247236 }
248237
249238 onOnline ( ) : void {
250- if (
251- this . observers . some (
252- observer =>
253- observer . isStale ( ) &&
254- observer . config . enabled &&
255- observer . config . refetchOnReconnect
256- )
257- ) {
258- this . fetch ( ) . catch ( noop )
239+ this . onInteraction ( false , true )
240+ }
241+
242+ private onInteraction ( focus : boolean , online : boolean ) : void {
243+ // Execute the last subscribed observer which is enabled,
244+ // stale and wants to refetch on this interaction.
245+ for ( let i = this . observers . length - 1 ; i >= 0 ; i -- ) {
246+ const observer = this . observers [ i ]
247+
248+ if (
249+ observer . isStale ( ) &&
250+ observer . config . enabled &&
251+ ( ( observer . config . refetchOnWindowFocus && focus ) ||
252+ ( observer . config . refetchOnReconnect && online ) )
253+ ) {
254+ observer . fetch ( ) . catch ( noop )
255+ break
256+ }
259257 }
260258
259+ // Continue any paused fetch
261260 this . continue ( )
262261 }
263262
Original file line number Diff line number Diff line change @@ -1220,6 +1220,62 @@ describe('useQuery', () => {
12201220 consoleMock . mockRestore ( )
12211221 } )
12221222
1223+ it ( 'should refetch after focus regain' , async ( ) => {
1224+ const key = queryKey ( )
1225+ const states : QueryResult < string > [ ] = [ ]
1226+ const consoleMock = mockConsoleError ( )
1227+
1228+ // make page unfocused
1229+ const originalVisibilityState = document . visibilityState
1230+ mockVisibilityState ( 'hidden' )
1231+
1232+ // set data in cache to check if the hook query fn is actually called
1233+ queryCache . setQueryData ( key , 'prefetched' )
1234+
1235+ function Page ( ) {
1236+ const state = useQuery ( key , ( ) => 'data' )
1237+ states . push ( state )
1238+ return null
1239+ }
1240+
1241+ render ( < Page /> )
1242+
1243+ await waitFor ( ( ) => expect ( states . length ) . toBe ( 2 ) )
1244+
1245+ act ( ( ) => {
1246+ // reset visibilityState to original value
1247+ mockVisibilityState ( originalVisibilityState )
1248+ window . dispatchEvent ( new FocusEvent ( 'focus' ) )
1249+ } )
1250+
1251+ await waitFor ( ( ) => expect ( states . length ) . toBe ( 4 ) )
1252+
1253+ expect ( states ) . toMatchObject ( [
1254+ {
1255+ data : 'prefetched' ,
1256+ isFetching : false ,
1257+ isStale : false ,
1258+ } ,
1259+ {
1260+ data : 'prefetched' ,
1261+ isFetching : false ,
1262+ isStale : true ,
1263+ } ,
1264+ {
1265+ data : 'prefetched' ,
1266+ isFetching : true ,
1267+ isStale : true ,
1268+ } ,
1269+ {
1270+ data : 'data' ,
1271+ isFetching : false ,
1272+ isStale : true ,
1273+ } ,
1274+ ] )
1275+
1276+ consoleMock . mockRestore ( )
1277+ } )
1278+
12231279 // See https://github.com/tannerlinsley/react-query/issues/195
12241280 it ( 'should refetch if stale after a prefetch' , async ( ) => {
12251281 const key = queryKey ( )
You can’t perform that action at this time.
0 commit comments