Skip to content

Commit

Permalink
Add a suspenseCache option to useSuspenseQuery (#10594)
Browse files Browse the repository at this point in the history
Co-authored-by: Lenz Weber-Tronic <lenz@apollographql.com>
Co-authored-by: Jerel Miller <jerelmiller@gmail.com>
  • Loading branch information
3 people authored Feb 23, 2023
1 parent fe19232 commit f221b5e
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/curvy-dragons-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@apollo/client': patch
---

Add a `suspenseCache` option to `useSuspenseQuery`
43 changes: 41 additions & 2 deletions src/react/hooks/__tests__/useSuspenseQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -298,14 +298,53 @@ describe('useSuspenseQuery', () => {
});
}).toThrowError(
new InvariantError(
'Could not find a "suspenseCache" in the context. Wrap the root component ' +
'in an <ApolloProvider> and provide a suspenseCache.'
'Could not find a "suspenseCache" in the context or passed in as an option. ' +
'Wrap the root component in an <ApolloProvider> and provide a suspenseCache, ' +
'or pass a SuspenseCache instance in via options.'
)
);

consoleSpy.mockRestore();
});

it('does not throw when provided a `suspenseCache` option', () => {
const { query } = useSimpleQueryCase();

const client = new ApolloClient({ cache: new InMemoryCache() });
const suspenseCache = new SuspenseCache();

expect(() => {
renderHook(() => useSuspenseQuery(query, { suspenseCache }), {
wrapper: ({ children }) => (
<ApolloProvider client={client} suspenseCache={undefined}>
{children}
</ApolloProvider>
),
});
}).not.toThrow();
});

it('prioritizes the `suspenseCache` option over the context value', () => {
const { query } = useSimpleQueryCase();

const directSuspenseCache = new SuspenseCache();
const contextSuspenseCache = new SuspenseCache();

renderHook(
() => useSuspenseQuery(query, { suspenseCache: directSuspenseCache }),
{
wrapper: ({ children }) => (
<MockedProvider suspenseCache={contextSuspenseCache}>
{children}
</MockedProvider>
),
}
);

expect(directSuspenseCache.lookup(query, {})).toBeTruthy();
expect(contextSuspenseCache.lookup(query, {})).not.toBeTruthy();
});

it('ensures a valid fetch policy is used', () => {
const INVALID_FETCH_POLICIES = ['cache-only', 'standby'];
const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
Expand Down
11 changes: 7 additions & 4 deletions src/react/hooks/useSuspenseCache.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { useContext } from 'react';
import { getApolloContext } from '../context';
import { invariant } from '../../utilities/globals';
import { SuspenseCache } from '../cache';

export function useSuspenseCache() {
const { suspenseCache } = useContext(getApolloContext());
export function useSuspenseCache(override?: SuspenseCache) {
const context = useContext(getApolloContext());
const suspenseCache = override || context.suspenseCache;

invariant(
suspenseCache,
'Could not find a "suspenseCache" in the context. Wrap the root component ' +
'in an <ApolloProvider> and provide a suspenseCache.'
'Could not find a "suspenseCache" in the context or passed in as an option. ' +
'Wrap the root component in an <ApolloProvider> and provide a suspenseCache, ' +
'or pass a SuspenseCache instance in via options.'
);

return suspenseCache;
Expand Down
2 changes: 1 addition & 1 deletion src/react/hooks/useSuspenseQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function useSuspenseQuery_experimental<
query: DocumentNode | TypedDocumentNode<TData, TVariables>,
options: SuspenseQueryHookOptions<TData, TVariables> = Object.create(null)
): UseSuspenseQueryResult<TData, TVariables> {
const suspenseCache = useSuspenseCache();
const suspenseCache = useSuspenseCache(options.suspenseCache);
const client = useApolloClient(options.client);
const watchQueryOptions = useWatchQueryOptions({ query, options, client });
const previousWatchQueryOptionsRef = useRef(watchQueryOptions);
Expand Down
2 changes: 2 additions & 0 deletions src/react/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
WatchQueryFetchPolicy,
} from '../../core';
import { NextFetchPolicyContext } from '../../core/watchQueryOptions';
import { SuspenseCache } from '../cache';

/* Common types */

Expand Down Expand Up @@ -138,6 +139,7 @@ export interface SuspenseQueryHookOptions<
context: NextFetchPolicyContext<TData, TVariables>
) => SuspenseQueryHookFetchPolicy);
suspensePolicy?: SuspensePolicy;
suspenseCache?: SuspenseCache;
}

/**
Expand Down

0 comments on commit f221b5e

Please sign in to comment.