Repository: tannerlinsley/react-query (ts)

Issue:
placeholderData not applied when query is disabled
**Describe the bug**
When there're query dependent, the last query:
1. `placeholderData` not applied until the query is fetching.
2. `isLoading` never triggerd.

**To Reproduce**
online sandbox:
https://codesandbox.io/s/react-query-issue-et8hs?file=/src/index.js

I have two querys: `auth`, `getUserDetail`.
 `getUserDetail` depends on `auth`.

The fetching order will be: `auth` -> `getUserDetail`.

`placeholderData` of `getUserDetail` is set to "placeholder"

1. when `auth` is fetching, the `placeholderData` of `getUserDetail` is `undefined` (BUG ?).
2. when `getUserDetail` is fetching, the `placeholderData` of `getUserDetail` is "placeholder" .
3. `isLoading` of `getUserDetail` is never been `true` (BUG ? I want to make sure this is expect behavior.).

**Expected behavior**
1. `placeholderData` applied at start (isIdle).

**Desktop (please complete the following information):**
 - Device: [PC]
 - OS: [Win10]
 - Browser: [edge(chromium)]


**Additional context**


Pull request:
fix (useQuery): apply placeholderData also to disabled queries
by checking for the idle state. this will make idle queries with placeholderData show up as success queries for the observer immediately

closes #1749 

Patch:
diff --git a/src/core/queriesObserver.ts b/src/core/queriesObserver.ts
index e133d7c3f..e936ee7e8 100644
--- a/src/core/queriesObserver.ts
+++ b/src/core/queriesObserver.ts
@@ -85,7 +85,7 @@ export class QueriesObserver extends Subscribable<QueriesObserverListener> {
       let hasIndexChange = false
 
       const prevObservers = this.observers
-      const prevOberversMap = this.observersMap
+      const prevObserversMap = this.observersMap
 
       const newResult: QueryObserverResult[] = []
       const newObservers: QueryObserver[] = []
@@ -98,7 +98,7 @@ export class QueriesObserver extends Subscribable<QueriesObserverListener> {
         const queryHash = defaultedOptions.queryHash!
         const observer = this.getObserver(defaultedOptions)
 
-        if (prevOberversMap[queryHash]) {
+        if (prevObserversMap[queryHash]) {
           observer.setOptions(defaultedOptions, notifyOptions)
         }
 
diff --git a/src/core/queryObserver.ts b/src/core/queryObserver.ts
index e1295cbd3..fd5bcafbc 100644
--- a/src/core/queryObserver.ts
+++ b/src/core/queryObserver.ts
@@ -495,7 +495,7 @@ export class QueryObserver<
     if (
       typeof options.placeholderData !== 'undefined' &&
       typeof data === 'undefined' &&
-      status === 'loading'
+      (status === 'loading' || status === 'idle')
     ) {
       let placeholderData
 


Test patch:
diff --git a/src/core/tests/queryObserver.test.tsx b/src/core/tests/queryObserver.test.tsx
index 1e4c6d36d..c94c0bfe1 100644
--- a/src/core/tests/queryObserver.test.tsx
+++ b/src/core/tests/queryObserver.test.tsx
@@ -473,8 +473,8 @@ describe('queryObserver', () => {
     })
 
     expect(observer.getCurrentResult()).toMatchObject({
-      status: 'idle',
-      data: undefined,
+      status: 'success',
+      data: 'placeholder',
     })
 
     const results: QueryObserverResult<unknown>[] = []
diff --git a/src/react/tests/useQuery.test.tsx b/src/react/tests/useQuery.test.tsx
index ae35708ca..12b6cd69a 100644
--- a/src/react/tests/useQuery.test.tsx
+++ b/src/react/tests/useQuery.test.tsx
@@ -3489,6 +3489,64 @@ describe('useQuery', () => {
     ])
   })
 
+  it('should use placeholder data even for disabled queries', async () => {
+    const key1 = queryKey()
+
+    const states: { state: UseQueryResult<string>; count: number }[] = []
+
+    function Page() {
+      const [count, setCount] = React.useState(0)
+
+      const state = useQuery(key1, () => 'data', {
+        placeholderData: 'placeholder',
+        enabled: count === 0,
+      })
+
+      states.push({ state, count })
+
+      React.useEffect(() => {
+        setCount(1)
+      }, [])
+
+      return (
+        <div>
+          <h2>Data: {state.data}</h2>
+          <div>Status: {state.status}</div>
+        </div>
+      )
+    }
+
+    const rendered = renderWithClient(queryClient, <Page />)
+    await waitFor(() => rendered.getByText('Data: data'))
+
+    expect(states).toMatchObject([
+      {
+        state: {
+          isSuccess: true,
+          isPlaceholderData: true,
+          data: 'placeholder',
+        },
+        count: 0,
+      },
+      {
+        state: {
+          isSuccess: true,
+          isPlaceholderData: true,
+          data: 'placeholder',
+        },
+        count: 1,
+      },
+      {
+        state: {
+          isSuccess: true,
+          isPlaceholderData: false,
+          data: 'data',
+        },
+        count: 1,
+      },
+    ])
+  })
+
   it('placeholder data should run through select', async () => {
     const key1 = queryKey()