Skip to content

Commit

Permalink
Update nextjs preload query w/ defer to use useSuspenseFragment
Browse files Browse the repository at this point in the history
  • Loading branch information
jerelmiller committed Feb 10, 2025
1 parent 9b0fbaa commit ca6552f
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import {
useApolloClient,
useQueryRefHandlers,
useReadQuery,
useSuspenseFragment,
} from "@apollo/client";
import { DeferredDynamicProductResult } from "@integration-test/shared/queries";
import {
DeferredDynamicProductResult,
RATING_FRAGMENT,
} from "@integration-test/shared/queries";
import { TransportedQueryRef } from "@apollo/experimental-nextjs-app-support";
import { useTransition } from "react";
import { Suspense, useTransition } from "react";

export function ClientChild({
queryRef,
Expand All @@ -17,40 +21,25 @@ export function ClientChild({
const { refetch } = useQueryRefHandlers(queryRef);
const [refetching, startTransition] = useTransition();
const { data } = useReadQuery(queryRef);
const client = useApolloClient();

return (
<>
<ul>
{data.products.map(({ id, title, rating }) => (
<li key={id}>
{title}
{data.products.map((product) => (
<li key={product.id}>
{product.title}
<br />
Rating:{" "}
<div style={{ display: "inline-block", verticalAlign: "text-top" }}>
{rating?.value || ""}
<br />
{rating ? `Queried in ${rating.env} environment` : "loading..."}
</div>
<Suspense fallback="Loading rating...">
<Rating product={product} delayDeferred={1000} />
</Suspense>
</li>
))}
</ul>
<p>Queried in {data.env} environment</p>
<button
disabled={refetching}
onClick={() => {
client.cache.batch({
update(cache) {
for (const product of data.products) {
cache.modify({
id: cache.identify(product),
fields: {
rating: () => null,
},
});
}
},
});
startTransition(() => {
refetch();
});
Expand All @@ -61,3 +50,28 @@ export function ClientChild({
</>
);
}

interface RatingProps {
product: { __typename: "Product"; id: string };
delayDeferred: number;
}

function Rating({ product, delayDeferred }: RatingProps) {
const { data } = useSuspenseFragment({
fragment: RATING_FRAGMENT,
from: product,
variables: {
delayDeferred,
},
});

const { rating } = data;

return (
<div style={{ display: "inline-block", verticalAlign: "text-top" }}>
{rating.value || ""}
<br />
Queried in {rating.env} environment
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ApolloWrapper } from "@/app/cc/ApolloWrapper";
import { ClientChild } from "./ClientChild";
import { DEFERRED_QUERY } from "@integration-test/shared/queries";
import { DEFERRED_QUERY_WITH_FRAGMENT } from "@integration-test/shared/queries";

export const dynamic = "force-dynamic";
import { PreloadQuery } from "../../../client";
Expand All @@ -10,7 +10,7 @@ export default async function Page({ searchParams }: { searchParams?: any }) {
return (
<ApolloWrapper>
<PreloadQuery
query={DEFERRED_QUERY}
query={DEFERRED_QUERY_WITH_FRAGMENT}
context={{
delay: 1000,
error: (await searchParams)?.errorIn || undefined,
Expand Down
34 changes: 33 additions & 1 deletion integration-test/shared/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ export const QUERY: TypedDocumentNode<

export interface DeferredDynamicProductResult {
products: {
__typename: "Product";
id: string;
title: string;
rating: undefined | { value: string; env: string };
rating: undefined | { __typename: "Rating"; value: string; env: string };
}[];
env: string;
}
Expand All @@ -46,3 +47,34 @@ export const DEFERRED_QUERY: TypedDocumentNode<
env
}
`;

export const RATING_FRAGMENT: TypedDocumentNode<
{
__typename: "Product";
rating: { __typename: "Rating"; value: string; env: string };
},
{ delayDeferred: number }
> = gql`
fragment RatingFragment on Product {
rating(delay: $delayDeferred) {
value
env
}
}
`;

export const DEFERRED_QUERY_WITH_FRAGMENT: TypedDocumentNode<
DeferredDynamicProductResult,
{ someArgument?: string; delayDeferred: number }
> = gql`
query dynamicProducts($delayDeferred: Int!, $someArgument: String) {
products(someArgument: $someArgument) {
id
title
...RatingFragment @defer
}
env
}
${RATING_FRAGMENT}
`;

0 comments on commit ca6552f

Please sign in to comment.