diff --git a/src/react/data/QueryData.ts b/src/react/data/QueryData.ts index 71e05d0f718..1c736caa483 100644 --- a/src/react/data/QueryData.ts +++ b/src/react/data/QueryData.ts @@ -101,11 +101,7 @@ export class QueryData extends OperationData< public afterExecute({ lazy = false }: { lazy?: boolean } = {}) { this.isMounted = true; const options = this.getOptions(); - if ( - this.currentObservable && - !this.ssrInitiated() && - !this.client.disableNetworkFetches - ) { + if (this.currentObservable && !this.ssrInitiated()) { this.startQuerySubscription(); } diff --git a/src/react/hooks/__tests__/useQuery.test.tsx b/src/react/hooks/__tests__/useQuery.test.tsx index 23cdda27b90..c001ce0fb4e 100644 --- a/src/react/hooks/__tests__/useQuery.test.tsx +++ b/src/react/hooks/__tests__/useQuery.test.tsx @@ -523,6 +523,74 @@ describe('useQuery Hook', () => { expect(result.current.loading).toBe(false); expect(result.current.data).toEqual(mocks[1].result.data); }); + + it('should use the cache when in ssrMode and fetchPolicy is `network-only`', async () => { + const query = gql`query { hello }`; + const link = mockSingleLink( + { + request: { query }, + result: { data: { hello: 'from link' } }, + }, + ); + + const cache = new InMemoryCache(); + cache.writeQuery({ + query, + data: { hello: 'from cache' }, + }); + + const client = new ApolloClient({ link, cache, ssrMode: true, }); + const { result, waitForNextUpdate } = renderHook( + () => useQuery(query, { fetchPolicy: 'network-only' }), + { + wrapper: ({ children }) => ( + + {children} + + ), + }, + ); + + expect(result.current.loading).toBe(false); + expect(result.current.data).toEqual({ hello: 'from cache' }); + + await expect(waitForNextUpdate({ timeout: 20 })) + .rejects.toThrow('Timed out'); + }); + + it('should not hang when ssrMode is true but the cache is not populated for some reason', async () => { + const query = gql`query { hello }`; + const link = mockSingleLink( + { + request: { query }, + result: { data: { hello: 'from link' } }, + }, + ); + + const client = new ApolloClient({ + link, + cache: new InMemoryCache(), + ssrMode: true, + }); + const { result, waitForNextUpdate } = renderHook( + () => useQuery(query), + { + wrapper: ({ children }) => ( + + {children} + + ), + }, + ); + + expect(result.current.loading).toBe(true); + expect(result.current.data).toBe(undefined); + + await waitForNextUpdate(); + + expect(result.current.loading).toBe(false); + expect(result.current.data).toEqual({ hello: 'from link' }); + }); }); describe('polling', () => { diff --git a/src/react/ssr/__tests__/useQuery.test.tsx b/src/react/ssr/__tests__/useQuery.test.tsx index cbf86af997c..0e5aacb584b 100644 --- a/src/react/ssr/__tests__/useQuery.test.tsx +++ b/src/react/ssr/__tests__/useQuery.test.tsx @@ -6,7 +6,6 @@ import { ApolloClient } from '../../../core'; import { InMemoryCache } from '../../../cache'; import { ApolloProvider } from '../../context'; import { useApolloClient, useQuery } from '../../hooks'; -import { render, wait } from '@testing-library/react'; import { renderToStringWithData } from '..'; describe('useQuery Hook SSR', () => { @@ -109,9 +108,7 @@ describe('useQuery Hook SSR', () => { }); }); - it( - 'should skip both SSR tree rendering and SSR component rendering if ' + - '`ssr` option is `false` and `ssrMode` is `true`', + it('should skip both SSR tree rendering and SSR component rendering if `ssr` option is `false` and `ssrMode` is `true`', async () => { const link = mockSingleLink({ request: { query: CAR_QUERY }, @@ -136,6 +133,7 @@ describe('useQuery Hook SSR', () => { break; case 1: // FAIL; should not render a second time default: + throw new Error("Duplicate render"); } renderCount += 1; @@ -148,22 +146,12 @@ describe('useQuery Hook SSR', () => { ); - await renderToStringWithData(app).then(result => { - expect(renderCount).toBe(1); - expect(result).toEqual(''); - }); - - renderCount = 0; - - render( - - - - ); - - await wait(() => { - expect(renderCount).toBe(1); - }); + const result = await renderToStringWithData(app); + expect(renderCount).toBe(1); + expect(result).toEqual(''); + await new Promise((resolve) => setTimeout(resolve, 20)); + expect(renderCount).toBe(1); + expect(result).toEqual(''); } );