Skip to content

Commit 78d6615

Browse files
committed
fix: use hook config on refocus or reconnect
1 parent 4df81f8 commit 78d6615

File tree

2 files changed

+76
-21
lines changed

2 files changed

+76
-21
lines changed

src/core/query.ts

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff 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

src/react/tests/useQuery.test.tsx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff 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()

0 commit comments

Comments
 (0)