diff --git a/packages/query-core/src/__tests__/queryObserver.test.tsx b/packages/query-core/src/__tests__/queryObserver.test.tsx
index fa3890000d..d54da63309 100644
--- a/packages/query-core/src/__tests__/queryObserver.test.tsx
+++ b/packages/query-core/src/__tests__/queryObserver.test.tsx
@@ -1,3 +1,4 @@
+import { waitFor } from '@testing-library/dom'
 import {
   afterEach,
   beforeEach,
@@ -7,8 +8,8 @@ import {
   test,
   vi,
 } from 'vitest'
-import { waitFor } from '@testing-library/dom'
 import { QueryObserver, focusManager } from '..'
+import { pendingThenable } from '../thenable'
 import { createQueryClient, queryKey, sleep } from './utils'
 import type { QueryClient, QueryObserverResult } from '..'
 
@@ -1233,4 +1234,38 @@ describe('queryObserver', () => {
 
     unsubscribe()
   })
+
+  test('switching enabled state should reuse the same promise', async () => {
+    const key = queryKey()
+
+    const observer = new QueryObserver(queryClient, {
+      queryKey: key,
+      enabled: false,
+      queryFn: () => 'data',
+    })
+    const results: Array<QueryObserverResult> = []
+
+    const success = pendingThenable<void>()
+
+    const unsubscribe = observer.subscribe((result) => {
+      results.push(result)
+
+      if (result.status === 'success') {
+        success.resolve()
+      }
+    })
+
+    observer.setOptions({
+      queryKey: key,
+      queryFn: () => 'data',
+      enabled: true,
+    })
+
+    await success
+
+    unsubscribe()
+
+    const promises = new Set(results.map((result) => result.promise))
+    expect(promises.size).toBe(1)
+  })
 })
diff --git a/packages/react-query/src/__tests__/useQuery.promise.test.tsx b/packages/react-query/src/__tests__/useQuery.promise.test.tsx
index ec07d2d2b2..440e0119b5 100644
--- a/packages/react-query/src/__tests__/useQuery.promise.test.tsx
+++ b/packages/react-query/src/__tests__/useQuery.promise.test.tsx
@@ -1377,4 +1377,72 @@ describe('useQuery().promise', () => {
         .observers.length,
     ).toBe(2)
   })
+
+  it('should handle enabled state changes with suspense', async () => {
+    const key = queryKey()
+    const renderStream = createRenderStream({ snapshotDOM: true })
+    const queryFn = vi.fn(async () => {
+      await sleep(1)
+      return 'test'
+    })
+
+    function MyComponent(props: { enabled: boolean }) {
+      const query = useQuery({
+        queryKey: key,
+        queryFn,
+        enabled: props.enabled,
+        staleTime: Infinity,
+      })
+
+      const data = React.use(query.promise)
+      return <>{data}</>
+    }
+
+    function Loading() {
+      return <>loading..</>
+    }
+
+    function Page() {
+      const enabledState = React.useState(false)
+      const enabled = enabledState[0]
+      const setEnabled = enabledState[1]
+
+      return (
+        <div>
+          <button onClick={() => setEnabled(true)}>enable</button>
+          <React.Suspense fallback={<Loading />}>
+            <MyComponent enabled={enabled} />
+          </React.Suspense>
+        </div>
+      )
+    }
+
+    const rendered = await renderStream.render(
+      <QueryClientProvider client={queryClient}>
+        <Page />
+      </QueryClientProvider>,
+    )
+
+    {
+      const result = await renderStream.takeRender()
+      result.withinDOM().getByText('loading..')
+    }
+
+    expect(queryFn).toHaveBeenCalledTimes(0)
+    rendered.getByText('enable').click()
+
+    {
+      const result = await renderStream.takeRender()
+      result.withinDOM().getByText('loading..')
+    }
+
+    expect(queryFn).toHaveBeenCalledTimes(1)
+
+    {
+      const result = await renderStream.takeRender()
+      result.withinDOM().getByText('test')
+    }
+
+    expect(queryFn).toHaveBeenCalledTimes(1)
+  })
 })
diff --git a/packages/react-query/src/useBaseQuery.ts b/packages/react-query/src/useBaseQuery.ts
index bcbf700ef7..25de99ee3c 100644
--- a/packages/react-query/src/useBaseQuery.ts
+++ b/packages/react-query/src/useBaseQuery.ts
@@ -70,9 +70,7 @@ export function useBaseQuery<
   useClearResetErrorBoundary(errorResetBoundary)
 
   // this needs to be invoked before creating the Observer because that can create a cache entry
-  const isNewCacheEntry = !client
-    .getQueryCache()
-    .get(defaultedOptions.queryHash)
+  const cacheEntry = client.getQueryCache().get(defaultedOptions.queryHash)
 
   const [observer] = React.useState(
     () =>
@@ -143,7 +141,16 @@ export function useBaseQuery<
     !isServer &&
     willFetch(result, isRestoring)
   ) {
-    const promise = isNewCacheEntry
+    // This fetching in the render should likely be done as part of the getOptimisticResult() considering https://github.com/TanStack/query/issues/8507
+    const state = cacheEntry?.state
+
+    const shouldFetch =
+      !state ||
+      (state.data === undefined &&
+        state.status === 'pending' &&
+        state.fetchStatus === 'idle')
+
+    const promise = shouldFetch
       ? // Fetch immediately on render in order to ensure `.promise` is resolved even if the component is unmounted
         fetchOptimistic(defaultedOptions, observer, errorResetBoundary)
       : // subscribe to the "cache promise" so that we can finalize the currentThenable once data comes in