Skip to content

Commit ed20b6d

Browse files
authored
fix(react): do not go into optimistic fetching state when not subscribed (#10759)
* fix(react): do not go into optimistic fetching state when not subscribed * changeset
1 parent 3f10705 commit ed20b6d

3 files changed

Lines changed: 47 additions & 2 deletions

File tree

.changeset/strong-toes-knock.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@tanstack/react-query': patch
3+
---
4+
5+
fix(react-query): do not go into optimistic fetching state when not subscribed

packages/react-query/src/__tests__/useQuery.test.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5916,6 +5916,42 @@ describe('useQuery', () => {
59165916
).toBe(1)
59175917
})
59185918

5919+
it('should not optimistically show fetching when unsubscribed', async () => {
5920+
const key = queryKey()
5921+
const queryFn = vi.fn(() => Promise.resolve('data'))
5922+
5923+
function Page() {
5924+
const [subscribed, setSubscribed] = React.useState(true)
5925+
const query = useQuery({
5926+
queryKey: key,
5927+
queryFn,
5928+
subscribed,
5929+
})
5930+
5931+
return (
5932+
<div>
5933+
<span>isFetching: {String(query.isFetching)}</span>
5934+
<span>fetchStatus: {query.fetchStatus}</span>
5935+
<button onClick={() => setSubscribed(false)}>unsubscribe</button>
5936+
</div>
5937+
)
5938+
}
5939+
5940+
const rendered = renderWithClient(queryClient, <Page />)
5941+
await vi.advanceTimersByTimeAsync(0)
5942+
rendered.getByText('isFetching: false')
5943+
rendered.getByText('fetchStatus: idle')
5944+
5945+
fireEvent.click(rendered.getByRole('button', { name: 'unsubscribe' }))
5946+
5947+
expect(queryFn).toHaveBeenCalledTimes(1)
5948+
expect(
5949+
queryClient.getQueryCache().find({ queryKey: key })!.observers.length,
5950+
).toBe(0)
5951+
rendered.getByText('isFetching: false')
5952+
rendered.getByText('fetchStatus: idle')
5953+
})
5954+
59195955
it('should not be attached to the query when subscribed is false', async () => {
59205956
const key = queryKey()
59215957
const queryFn = vi.fn(() => Promise.resolve('data'))

packages/react-query/src/useBaseQuery.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,14 @@ export function useBaseQuery<
7474
}
7575
}
7676

77+
const subscribed = options.subscribed !== false
78+
7779
// Make sure results are optimistically set in fetching state before subscribing or updating options
7880
defaultedOptions._optimisticResults = isRestoring
7981
? 'isRestoring'
80-
: 'optimistic'
82+
: subscribed
83+
? 'optimistic'
84+
: undefined
8185

8286
ensureSuspenseTimers(defaultedOptions)
8387
ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary, query)
@@ -99,7 +103,7 @@ export function useBaseQuery<
99103
// note: this must be called before useSyncExternalStore
100104
const result = observer.getOptimisticResult(defaultedOptions)
101105

102-
const shouldSubscribe = !isRestoring && options.subscribed !== false
106+
const shouldSubscribe = !isRestoring && subscribed
103107
React.useSyncExternalStore(
104108
React.useCallback(
105109
(onStoreChange) => {

0 commit comments

Comments
 (0)