Repository: TanStack/query
Pull request #5997 (2023-09-12 18:10:30)

fix: avoid reverting state to a fetching one
fixes https://github.com/TanStack/query/issues/5968 , cc @TkDodo @KartheekJavvaji 

vercel[bot]: [vc]: #8ICX3Gd6z2coPcvUV0RvzslIPKZYLOIh8OZ/xKbJH4c=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJxdWVyeSIsInJvb3REaXJlY3RvcnkiOiJkb2NzIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL3RhbnN0YWNrL3F1ZXJ5L0RaZkpzQUNkUk4yMVppdEtUdXNmSlgyZTNjRlgiLCJwcmV2aWV3VXJsIjoicXVlcnktZ2l0LWZvcmstYW5kYXJpc3QtZml4LXJldmVydGluZy10by1mZXRjaGluZy10YW5zdGFjay52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IlBFTkRJTkciLCJsaXZlRmVlZGJhY2siOnsicmVzb2x2ZWQiOjAsInVucmVzb2x2ZWQiOjAsInRvdGFsIjowLCJsaW5rIjoicXVlcnktZ2l0LWZvcmstYW5kYXJpc3QtZml4LXJldmVydGluZy10by1mZXRjaGluZy10YW5zdGFjay52ZXJjZWwuYXBwIn19XX0=
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **query** | 🔄 Building ([Inspect](https://vercel.com/tanstack/query/DZfJsACdRN21ZitKTusfJX2e3cFX)) | [Visit Preview](https://vercel.live/open-feedback/query-git-fork-andarist-fix-reverting-to-fetching-tanstack.vercel.app?via=pr-comment-visit-preview-link&passThrough=1) | 💬 [**Add feedback**](https://vercel.live/open-feedback/query-git-fork-andarist-fix-reverting-to-fetching-tanstack.vercel.app?via=pr-comment-feedback-link) | Sep 12, 2023 6:10pm |


nx-cloud[bot]: # ☁️ Nx Cloud Report

CI is running for commit 3e9658b97f4a3a07526d323ef9bece881f88547e.

[📂 Click to track the progress, see the status, the terminal output, and the build insights.](https://cloud.nx.app/branch?workspaceId=6412c827e6da5d7b4a0b1fe3&branchName=5997,fix/reverting-to-fetching)


---

Sent with 💌 from [NxCloud.](https://nx.app)
codesandbox-ci[bot]: This pull request is automatically built and testable in [CodeSandbox](https://codesandbox.io).

  To see build info of the built libraries, click [here](https://ci.codesandbox.io/status/TanStack/query/pr/5997/builds/417207) or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 3e9658b97f4a3a07526d323ef9bece881f88547e:

|Sandbox| Source |
|--|--|
|[@tanstack/query-example-react-basic-typescript](https://codesandbox.io/s/tanstack-query-example-react-basic-typescript-y3gzgl)| Configuration |
|[@tanstack/query-example-solid-basic-typescript](https://codesandbox.io/s/tanstack-query-example-solid-basic-typescript-76hytq)| Configuration |
|[@tanstack/query-example-svelte-basic](https://codesandbox.io/s/tanstack-query-example-svelte-basic-qwv5h8)| Configuration |
|[@tanstack/query-example-vue-basic](https://codesandbox.io/s/tanstack-query-example-vue-basic-cjxm56)| Configuration |

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/TanStack/query/pull/5997?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TanStack) Report
Patch coverage is **`100.00%`** of modified lines.

:exclamation: Your organization needs to install the [Codecov GitHub app](https://github.com/apps/codecov/installations/select_target) to enable full functionality.

| [Files Changed](https://app.codecov.io/gh/TanStack/query/pull/5997?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TanStack) | Coverage |
|---|---|
| [packages/query-core/src/query.ts](https://app.codecov.io/gh/TanStack/query/pull/5997?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TanStack#diff-cGFja2FnZXMvcXVlcnktY29yZS9zcmMvcXVlcnkudHM=) | `100.00%` |
| [packages/vue-query/src/useBaseQuery.ts](https://app.codecov.io/gh/TanStack/query/pull/5997?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TanStack#diff-cGFja2FnZXMvdnVlLXF1ZXJ5L3NyYy91c2VCYXNlUXVlcnkudHM=) | `100.00%` |
| [packages/vue-query/src/useIsFetching.ts](https://app.codecov.io/gh/TanStack/query/pull/5997?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TanStack#diff-cGFja2FnZXMvdnVlLXF1ZXJ5L3NyYy91c2VJc0ZldGNoaW5nLnRz) | `100.00%` |
| [packages/vue-query/src/useIsMutating.ts](https://app.codecov.io/gh/TanStack/query/pull/5997?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TanStack#diff-cGFja2FnZXMvdnVlLXF1ZXJ5L3NyYy91c2VJc011dGF0aW5nLnRz) | `100.00%` |


:loudspeaker: Thoughts on this report? [Let us know!](https://about.codecov.io/pull-request-comment-report/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TanStack).


Patch:
diff --git a/packages/query-core/src/query.ts b/packages/query-core/src/query.ts
index 3b3960e90..d334a0f83 100644
--- a/packages/query-core/src/query.ts
+++ b/packages/query-core/src/query.ts
@@ -559,7 +559,7 @@ export class Query<
           const error = action.error as unknown
 
           if (isCancelledError(error) && error.revert && this.revertState) {
-            return { ...this.revertState }
+            return { ...this.revertState, fetchStatus: 'idle' }
           }
 
           return {


Test patch:
diff --git a/packages/query-core/src/tests/query.test.tsx b/packages/query-core/src/tests/query.test.tsx
index dc2b2bfb2..fcc4ad023 100644
--- a/packages/query-core/src/tests/query.test.tsx
+++ b/packages/query-core/src/tests/query.test.tsx
@@ -911,4 +911,56 @@ describe('query', () => {
 
     unsubscribe()
   })
+
+  test('should always revert to idle state (#5958)', async () => {
+    let mockedData = [1]
+
+    const key = queryKey()
+
+    const queryFn = jest.fn<
+      Promise<unknown>,
+      [QueryFunctionContext<ReturnType<typeof queryKey>>]
+    >()
+
+    queryFn.mockImplementation(({ signal }) => {
+      return new Promise((resolve, reject) => {
+        const abortListener = () => {
+          clearTimeout(timerId)
+          reject(signal!.reason)
+        }
+        signal!.addEventListener('abort', abortListener)
+
+        const timerId = setTimeout(() => {
+          signal!.removeEventListener('abort', abortListener)
+          resolve(mockedData.join(' - '))
+        }, 50)
+      })
+    })
+
+    const observer = new QueryObserver(queryClient, {
+      queryKey: key,
+      queryFn,
+    })
+    const unsubscribe = observer.subscribe(() => undefined)
+    await sleep(60) // let it resolve
+
+    mockedData = [1, 2] // update "server" state in the background
+
+    queryClient.invalidateQueries(key)
+    await sleep(1)
+    queryClient.invalidateQueries(key)
+    await sleep(1)
+    unsubscribe() // unsubscribe to simulate unmount
+
+    // set up a new observer to simulate a mount of new component
+    const newObserver = new QueryObserver(queryClient, {
+      queryKey: key,
+      queryFn,
+    })
+
+    const spy = jest.fn()
+    newObserver.subscribe(({ data }) => spy(data))
+    await sleep(60) // let it resolve
+    expect(spy).toHaveBeenCalledWith('1 - 2')
+  })
 })