Created
January 11, 2026 05:40
-
-
Save Temzasse/41d99d20cd9a7452e127f2d5c4f9ea7a to your computer and use it in GitHub Desktop.
Enhanced version of `useSuspenseQuery` in Apollo Client for better DX with Suspense
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { useDeferredValue } from "react"; | |
| import { useSpinDelay } from "spin-delay"; | |
| import { equal } from "@wry/equality"; | |
| import { | |
| type DocumentNode, | |
| type TypedDocumentNode, | |
| type OperationVariables, | |
| } from "@apollo/client"; | |
| import { useSuspenseQuery as useApolloSuspenseQuery } from "@apollo/client/react"; | |
| /** | |
| * Enhance `useSuspenseQuery` hook to stop the hook from suspending when variables | |
| * change and instead return a `suspending` flag that can be used to shown an inline | |
| * loading indicator. | |
| * | |
| * More info: https://www.teemutaskula.com/blog/exploring-query-suspense#deferring-with-usedeferredvalue | |
| * (the article is written for React Query but the same concept applies to Apollo) | |
| */ | |
| export function useSuspenseQueryDeferred< | |
| TData = unknown, | |
| TVariables extends OperationVariables = OperationVariables | |
| >( | |
| query: DocumentNode | TypedDocumentNode<TData, TVariables>, | |
| options?: useApolloSuspenseQuery.Options<NoInfer<TVariables>> | |
| ) { | |
| const deferredVariables = useDeferredValue(options?.variables); | |
| const result = useApolloSuspenseQuery<TData, TVariables>(query, { | |
| ...options!, // TODO: figure out TS issue if `!` is removed | |
| variables: deferredVariables, | |
| }); | |
| /** | |
| * Add smart delay to prevent spinner flickering when variables change, | |
| * and tell when the query is suspending so that we can show an inline | |
| * loading indicator. | |
| */ | |
| const isSuspending = useSpinDelay( | |
| !equal(deferredVariables, options?.variables) | |
| ); | |
| return { ...result, isSuspending }; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment