Repository: tannerlinsley/react-query
Pull request #899 (2020-08-20 16:24:28)

fix: make sure observers only subscribe to queries when started
Fixes https://github.com/tannerlinsley/react-query/issues/896

vercel[bot]: This pull request is being automatically deployed with Vercel ([learn more](https://vercel.link/github-learn-more)).  
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: *In Progress*  
✅ Preview: *In Progress*



Patch:
diff --git a/src/core/queryObserver.ts b/src/core/queryObserver.ts
index 3e22560f8..0cec1786b 100644
--- a/src/core/queryObserver.ts
+++ b/src/core/queryObserver.ts
@@ -24,13 +24,14 @@ export class QueryObserver<TResult, TError> {
     this.refetch = this.refetch.bind(this)
     this.fetchMore = this.fetchMore.bind(this)
 
-    // Subscribe to query
+    // Subscribe to the query
     this.updateQuery()
   }
 
   subscribe(listener?: UpdateListener<TResult, TError>): () => void {
     this.started = true
     this.updateListener = listener
+    this.currentQuery.subscribeObserver(this)
     this.optionalFetch()
     this.updateRefetchInterval()
     return this.unsubscribe.bind(this)
@@ -204,11 +205,14 @@ export class QueryObserver<TResult, TError> {
     }
 
     this.previousResult = this.currentResult
-    prevQuery?.unsubscribeObserver(this)
     this.currentQuery = newQuery
-    newQuery.subscribeObserver(this)
     this.currentResult = this.createResult()
 
+    if (this.started) {
+      prevQuery?.unsubscribeObserver(this)
+      this.currentQuery.subscribeObserver(this)
+    }
+
     return true
   }
 
diff --git a/src/react/useBaseQuery.ts b/src/react/useBaseQuery.ts
index 3764bfe35..1a56cdd56 100644
--- a/src/react/useBaseQuery.ts
+++ b/src/react/useBaseQuery.ts
@@ -42,6 +42,7 @@ export function useBaseQuery<TResult, TError>(
     }
 
     if (config.enabled && config.suspense && !result.isSuccess) {
+      observer.subscribe()
       throw observer.fetch().finally(() => {
         observer.unsubscribe(true)
       })


Test patch:
diff --git a/src/react/tests/useQuery.test.tsx b/src/react/tests/useQuery.test.tsx
index 6d8e08e58..3837dbb1e 100644
--- a/src/react/tests/useQuery.test.tsx
+++ b/src/react/tests/useQuery.test.tsx
@@ -234,6 +234,48 @@ describe('useQuery', () => {
     })
   })
 
+  // https://github.com/tannerlinsley/react-query/issues/896
+  it('should fetch data in Strict mode when refetchOnMount is false', async () => {
+    const key = queryKey()
+    const states: QueryResult<string>[] = []
+
+    function Page() {
+      const state = useQuery(
+        key,
+        async () => {
+          await sleep(10)
+          return 'test'
+        },
+        {
+          refetchOnMount: false,
+        }
+      )
+      states.push(state)
+      return null
+    }
+
+    render(
+      <React.StrictMode>
+        <Page />
+      </React.StrictMode>
+    )
+
+    await waitFor(() => expect(states.length).toBe(4))
+
+    expect(states[0]).toMatchObject({
+      data: undefined,
+    })
+    expect(states[1]).toMatchObject({
+      data: undefined,
+    })
+    expect(states[2]).toMatchObject({
+      data: 'test',
+    })
+    expect(states[3]).toMatchObject({
+      data: 'test',
+    })
+  })
+
   it('should share equal data structures between query results', async () => {
     const key = queryKey()