Skip to content

Commit 9bf30b6

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

File tree

2 files changed

+80
-23
lines changed

2 files changed

+80
-23
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: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ describe('useQuery', () => {
644644

645645
await queryCache.prefetchQuery(key, () => 'prefetch')
646646

647-
await sleep(40)
647+
await sleep(20)
648648

649649
function FirstComponent() {
650650
const state = useQuery(key, () => 'one', {
@@ -656,7 +656,7 @@ describe('useQuery', () => {
656656

657657
function SecondComponent() {
658658
const state = useQuery(key, () => 'two', {
659-
staleTime: 20,
659+
staleTime: 10,
660660
})
661661
states2.push(state)
662662
return null
@@ -673,6 +673,8 @@ describe('useQuery', () => {
673673

674674
render(<Page />)
675675

676+
console.log(states2)
677+
676678
await waitFor(() => expect(states1.length).toBe(4))
677679
await waitFor(() => expect(states2.length).toBe(4))
678680

@@ -1220,6 +1222,62 @@ describe('useQuery', () => {
12201222
consoleMock.mockRestore()
12211223
})
12221224

1225+
it('should refetch after focus regain', async () => {
1226+
const key = queryKey()
1227+
const states: QueryResult<string>[] = []
1228+
const consoleMock = mockConsoleError()
1229+
1230+
// make page unfocused
1231+
const originalVisibilityState = document.visibilityState
1232+
mockVisibilityState('hidden')
1233+
1234+
// set data in cache to check if the hook query fn is actually called
1235+
queryCache.setQueryData(key, 'prefetched')
1236+
1237+
function Page() {
1238+
const state = useQuery(key, () => 'data')
1239+
states.push(state)
1240+
return null
1241+
}
1242+
1243+
render(<Page />)
1244+
1245+
await waitFor(() => expect(states.length).toBe(2))
1246+
1247+
act(() => {
1248+
// reset visibilityState to original value
1249+
mockVisibilityState(originalVisibilityState)
1250+
window.dispatchEvent(new FocusEvent('focus'))
1251+
})
1252+
1253+
await waitFor(() => expect(states.length).toBe(4))
1254+
1255+
expect(states).toMatchObject([
1256+
{
1257+
data: 'prefetched',
1258+
isFetching: false,
1259+
isStale: false,
1260+
},
1261+
{
1262+
data: 'prefetched',
1263+
isFetching: false,
1264+
isStale: true,
1265+
},
1266+
{
1267+
data: 'prefetched',
1268+
isFetching: true,
1269+
isStale: true,
1270+
},
1271+
{
1272+
data: 'data',
1273+
isFetching: false,
1274+
isStale: true,
1275+
},
1276+
])
1277+
1278+
consoleMock.mockRestore()
1279+
})
1280+
12231281
// See https://github.com/tannerlinsley/react-query/issues/195
12241282
it('should refetch if stale after a prefetch', async () => {
12251283
const key = queryKey()

0 commit comments

Comments
 (0)