diff --git a/.changeset/tall-moons-repeat.md b/.changeset/tall-moons-repeat.md
new file mode 100644
index 00000000000..b445ff975af
--- /dev/null
+++ b/.changeset/tall-moons-repeat.md
@@ -0,0 +1,5 @@
+---
+'@tanstack/preact-query': patch
+---
+
+fix(preact-query): do not go into optimistic fetching state when not subscribed
diff --git a/packages/preact-query/src/__tests__/useQueries.test.tsx b/packages/preact-query/src/__tests__/useQueries.test.tsx
index ccb3b3a34f4..6ca70b2828f 100644
--- a/packages/preact-query/src/__tests__/useQueries.test.tsx
+++ b/packages/preact-query/src/__tests__/useQueries.test.tsx
@@ -64,6 +64,34 @@ describe('useQueries', () => {
expect(results[2]).toMatchObject([{ data: 1 }, { data: 2 }])
})
+ it('should not optimistically show fetching when unsubscribed', () => {
+ const key = queryKey()
+ const queryFn = vi.fn(() => Promise.resolve('data'))
+
+ function Page() {
+ const [query] = useQueries({
+ queries: [{ queryKey: key, queryFn }],
+ subscribed: false,
+ })
+
+ return (
+
+ isFetching: {String(query.isFetching)}
+ fetchStatus: {query.fetchStatus}
+
+ )
+ }
+
+ const rendered = renderWithClient(queryClient, )
+
+ expect(queryFn).not.toHaveBeenCalled()
+ expect(
+ queryClient.getQueryCache().find({ queryKey: key })!.observers.length,
+ ).toBe(0)
+ rendered.getByText('isFetching: false')
+ rendered.getByText('fetchStatus: idle')
+ })
+
it('should track results', async () => {
const key1 = queryKey()
const results: Array> = []
diff --git a/packages/preact-query/src/__tests__/useQuery.test.tsx b/packages/preact-query/src/__tests__/useQuery.test.tsx
index 52c92ab5243..fed0f29ec46 100644
--- a/packages/preact-query/src/__tests__/useQuery.test.tsx
+++ b/packages/preact-query/src/__tests__/useQuery.test.tsx
@@ -5895,6 +5895,35 @@ describe('useQuery', () => {
).toBe(1)
})
+ it('should not optimistically show fetching when subscribed is false', () => {
+ const key = queryKey()
+ const queryFn = vi.fn(() => Promise.resolve('data'))
+
+ function Page() {
+ const query = useQuery({
+ queryKey: key,
+ queryFn,
+ subscribed: false,
+ })
+
+ return (
+
+ isFetching: {String(query.isFetching)}
+ fetchStatus: {query.fetchStatus}
+
+ )
+ }
+
+ const rendered = renderWithClient(queryClient, )
+
+ expect(queryFn).not.toHaveBeenCalled()
+ expect(
+ queryClient.getQueryCache().find({ queryKey: key })!.observers.length,
+ ).toBe(0)
+ rendered.getByText('isFetching: false')
+ rendered.getByText('fetchStatus: idle')
+ })
+
it('should not be attached to the query when subscribed is false', async () => {
const key = queryKey()
const queryFn = vi.fn(() => Promise.resolve('data'))
diff --git a/packages/preact-query/src/useBaseQuery.ts b/packages/preact-query/src/useBaseQuery.ts
index e5e37cbc52b..2ae163e5cb5 100644
--- a/packages/preact-query/src/useBaseQuery.ts
+++ b/packages/preact-query/src/useBaseQuery.ts
@@ -70,10 +70,14 @@ export function useBaseQuery<
}
}
+ const subscribed = options.subscribed !== false
+
// Make sure results are optimistically set in fetching state before subscribing or updating options
defaultedOptions._optimisticResults = isRestoring
? 'isRestoring'
- : 'optimistic'
+ : subscribed
+ ? 'optimistic'
+ : undefined
ensureSuspenseTimers(defaultedOptions)
ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary, query)
@@ -91,7 +95,7 @@ export function useBaseQuery<
// note: this must be called before useSyncExternalStore
const result = observer.getOptimisticResult(defaultedOptions)
- const shouldSubscribe = !isRestoring && options.subscribed !== false
+ const shouldSubscribe = !isRestoring && subscribed
useSyncExternalStore(
useCallback(
(onStoreChange) => {
diff --git a/packages/preact-query/src/useQueries.ts b/packages/preact-query/src/useQueries.ts
index dac252d0109..8c785c684f8 100644
--- a/packages/preact-query/src/useQueries.ts
+++ b/packages/preact-query/src/useQueries.ts
@@ -223,6 +223,7 @@ export function useQueries<
const client = useQueryClient(queryClient)
const isRestoring = useIsRestoring()
const errorResetBoundary = useQueryErrorResetBoundary()
+ const subscribed = options.subscribed !== false
const defaultedQueries = useMemo(
() =>
@@ -234,11 +235,13 @@ export function useQueries<
// Make sure the results are already in fetching state before subscribing or updating options
defaultedOptions._optimisticResults = isRestoring
? 'isRestoring'
- : 'optimistic'
+ : subscribed
+ ? 'optimistic'
+ : undefined
return defaultedOptions
}),
- [queries, client, isRestoring],
+ [queries, client, isRestoring, subscribed],
)
defaultedQueries.forEach((queryOptions) => {
@@ -265,7 +268,7 @@ export function useQueries<
(options as QueriesObserverOptions).combine,
)
- const shouldSubscribe = !isRestoring && options.subscribed !== false
+ const shouldSubscribe = !isRestoring && subscribed
useSyncExternalStore(
useCallback(
(onStoreChange) =>