Skip to content

Commit a8ffaa9

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

File tree

2 files changed

+76
-23
lines changed

2 files changed

+76
-23
lines changed

src/core/query.ts

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -232,32 +232,29 @@ 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 first observer which is enabled,
244+
// stale and wants to refetch on this interaction.
245+
const observer = this.observers.find(
246+
observer =>
247+
observer.isStale() &&
248+
observer.config.enabled &&
249+
((observer.config.refetchOnWindowFocus && focus) ||
250+
(observer.config.refetchOnReconnect && online))
251+
)
252+
253+
if (observer) {
254+
observer.fetch().catch(noop)
259255
}
260256

257+
// Continue any paused fetch
261258
this.continue()
262259
}
263260

src/react/tests/useQuery.test.tsx

Lines changed: 58 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
@@ -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)