Skip to content

Commit 67d41a6

Browse files
Remove unsubscribed data on refocus instead of refetching them (#1974)
* Refetch should not happen if no active subscribers Fixes #1530 * Changed logic and added test * Forgot to remove test that should not be merged * Fix return typo and rearranged logic
1 parent fee16b9 commit 67d41a6

File tree

2 files changed

+57
-7
lines changed

2 files changed

+57
-7
lines changed

packages/toolkit/src/query/core/buildMiddleware/windowEventHandling.ts

+14-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { QueryStatus } from '../apiState'
2+
import type { QueryCacheKey } from '../apiState'
23
import { onFocus, onOnline } from '../setupListeners'
34
import type { SubMiddlewareApi, SubMiddlewareBuilder } from './types'
45

56
export const build: SubMiddlewareBuilder = ({
67
reducerPath,
78
context,
9+
api,
810
refetchQuery,
911
}) => {
12+
const { removeQueryResult } = api.internalActions
13+
1014
return (mwApi) =>
1115
(next) =>
1216
(action): any => {
@@ -35,12 +39,7 @@ export const build: SubMiddlewareBuilder = ({
3539
const querySubState = queries[queryCacheKey]
3640
const subscriptionSubState = subscriptions[queryCacheKey]
3741

38-
if (
39-
!subscriptionSubState ||
40-
!querySubState ||
41-
querySubState.status === QueryStatus.uninitialized
42-
)
43-
return
42+
if (!subscriptionSubState || !querySubState) continue
4443

4544
const shouldRefetch =
4645
Object.values(subscriptionSubState).some(
@@ -52,7 +51,15 @@ export const build: SubMiddlewareBuilder = ({
5251
state.config[type])
5352

5453
if (shouldRefetch) {
55-
api.dispatch(refetchQuery(querySubState, queryCacheKey))
54+
if (Object.keys(subscriptionSubState).length === 0) {
55+
api.dispatch(
56+
removeQueryResult({
57+
queryCacheKey: queryCacheKey as QueryCacheKey,
58+
})
59+
)
60+
} else if (querySubState.status !== QueryStatus.uninitialized) {
61+
api.dispatch(refetchQuery(querySubState, queryCacheKey))
62+
}
5663
}
5764
}
5865
})

packages/toolkit/src/query/tests/refetchingBehaviors.test.tsx

+43
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ const defaultApi = createApi({
3737

3838
const storeRef = setupApiStore(defaultApi)
3939

40+
let getIncrementedAmountState = () =>
41+
storeRef.store.getState().api.queries['getIncrementedAmount(undefined)']
42+
4043
afterEach(() => {
4144
amount = 0
4245
})
@@ -177,6 +180,46 @@ describe('refetchOnFocus tests', () => {
177180
expect(screen.getByTestId('amount').textContent).toBe('2')
178181
)
179182
})
183+
184+
test('useQuery hook cleans data if refetch without active subscribers', async () => {
185+
let data, isLoading, isFetching
186+
187+
function User() {
188+
;({ data, isFetching, isLoading } =
189+
defaultApi.endpoints.getIncrementedAmount.useQuery(undefined, {
190+
refetchOnFocus: true,
191+
}))
192+
return (
193+
<div>
194+
<div data-testid="isLoading">{String(isLoading)}</div>
195+
<div data-testid="isFetching">{String(isFetching)}</div>
196+
<div data-testid="amount">{String(data?.amount)}</div>
197+
</div>
198+
)
199+
}
200+
201+
const { unmount } = render(<User />, { wrapper: storeRef.wrapper })
202+
203+
await waitFor(() =>
204+
expect(screen.getByTestId('isLoading').textContent).toBe('true')
205+
)
206+
await waitFor(() =>
207+
expect(screen.getByTestId('isLoading').textContent).toBe('false')
208+
)
209+
await waitFor(() =>
210+
expect(screen.getByTestId('amount').textContent).toBe('1')
211+
)
212+
213+
unmount()
214+
215+
expect(getIncrementedAmountState()).not.toBeUndefined()
216+
217+
act(() => {
218+
fireEvent.focus(window)
219+
})
220+
221+
expect(getIncrementedAmountState()).toBeUndefined()
222+
})
180223
})
181224

182225
describe('refetchOnReconnect tests', () => {

0 commit comments

Comments
 (0)