diff --git a/packages/toolkit/src/query/core/apiState.ts b/packages/toolkit/src/query/core/apiState.ts index 192d32190c..79b248ea35 100644 --- a/packages/toolkit/src/query/core/apiState.ts +++ b/packages/toolkit/src/query/core/apiState.ts @@ -87,6 +87,8 @@ export type SubscriptionOptions = { * Defaults to 'false'. This setting allows you to control whether RTK Query will continue polling if the window is not focused. * * If pollingInterval is not set or set to 0, this **will not be evaluated** until pollingInterval is greater than 0. + * + * Note: requires [`setupListeners`](./setupListeners) to have been called. */ skipPollOnFocusLost?: boolean /** diff --git a/packages/toolkit/src/query/core/buildMiddleware/polling.ts b/packages/toolkit/src/query/core/buildMiddleware/polling.ts index c05bb6ff6d..909aa94219 100644 --- a/packages/toolkit/src/query/core/buildMiddleware/polling.ts +++ b/packages/toolkit/src/query/core/buildMiddleware/polling.ts @@ -77,7 +77,7 @@ export const buildPollingHandler: InternalHandlerBuilder = ({ nextPollTimestamp, pollingInterval: lowestPollingInterval, timeout: setTimeout(() => { - if (document.hasFocus() || !skipPollOnFocusLost) { + if (state.config.focused || !skipPollOnFocusLost) { api.dispatch(refetchQuery(querySubState, queryCacheKey)) } startNextPoll({ queryCacheKey }, api) @@ -135,7 +135,9 @@ export const buildPollingHandler: InternalHandlerBuilder = ({ subscribers[key].pollingInterval!, lowestPollingInterval ) - skipPollOnFocusLost = subscribers[key].skipPollOnFocusLost + // if (!skipPollOnFocusLost) { + skipPollOnFocusLost = subscribers[key].skipPollOnFocusLost + // } } } diff --git a/packages/toolkit/src/query/tests/polling.test.tsx b/packages/toolkit/src/query/tests/polling.test.tsx index 2a21215ec3..258fbf7dbe 100644 --- a/packages/toolkit/src/query/tests/polling.test.tsx +++ b/packages/toolkit/src/query/tests/polling.test.tsx @@ -2,6 +2,8 @@ import { createApi } from '@reduxjs/toolkit/query' import { delay } from 'msw' import { setupApiStore } from './helpers' import type { SubscriptionSelectors } from '../core/buildMiddleware/types' +import { createListenerMiddleware } from '@reduxjs/toolkit' + const mockBaseQuery = vi .fn() @@ -125,18 +127,27 @@ describe('polling tests', () => { it('respects skipPollOnFocusLost', async () => { mockBaseQuery.mockClear() - storeRef.store.dispatch( - getPosts.initiate(1, { + const listenerMiddleware = createListenerMiddleware() + const storeListenerRef = setupApiStore(api, undefined, { + middleware: { + concat: [listenerMiddleware.middleware], + }, + withoutTestLifecycles: true, + }) + + storeListenerRef.store.dispatch( + getPosts.initiate(2, { subscriptionOptions: { pollingInterval: 10, skipPollOnFocusLost: true }, subscribe: true, }) ) + storeListenerRef.store.dispatch(api.internalActions?.onFocusLost()) - await delay(20) + await delay(50) const callsWithSkip = mockBaseQuery.mock.calls.length - storeRef.store.dispatch( - getPosts.initiate(1, { + storeListenerRef.store.dispatch( + getPosts.initiate(2, { subscriptionOptions: { pollingInterval: 10, skipPollOnFocusLost: false, @@ -145,17 +156,28 @@ describe('polling tests', () => { }) ) - await delay(30) + storeListenerRef.store.dispatch(api.internalActions?.onFocus()) + + await delay(50) const callsWithoutSkip = mockBaseQuery.mock.calls.length - console.log(callsWithSkip, callsWithoutSkip) expect(callsWithSkip).toBe(1) expect(callsWithoutSkip).toBeGreaterThan(2) + + storeListenerRef.store.dispatch(api.util.resetApiState()) }) - it('replaces skipPollOnFocusLost with most recent mount', async () => { - storeRef.store.dispatch( - getPosts.initiate(1, { + it('respects skipPollOnFocusLost if any subscription is true', async () => { + const listenerMiddleware = createListenerMiddleware() + const storeListenerRef = setupApiStore(api, undefined, { + middleware: { + concat: [listenerMiddleware.middleware], + }, + withoutTestLifecycles: true, + }) + + storeListenerRef.store.dispatch( + getPosts.initiate(3, { subscriptionOptions: { pollingInterval: 10, skipPollOnFocusLost: false, @@ -167,13 +189,15 @@ describe('polling tests', () => { await delay(50) const callsWithSkip = mockBaseQuery.mock.calls.length - storeRef.store.dispatch( - getPosts.initiate(1, { + storeListenerRef.store.dispatch( + getPosts.initiate(3, { subscriptionOptions: { pollingInterval: 15, skipPollOnFocusLost: true }, subscribe: true, }) ) + storeListenerRef.store.dispatch(api.internalActions?.onFocusLost()) + await delay(50) const callsWithoutSkip = mockBaseQuery.mock.calls.length