Next.js 14与@apollo/experimental-nextjs-app-support/ssr查询重复执行问题
Next.js 14 + Apollo实验库:服务端已执行查询,浏览器端仍重复发起请求并显示Suspense加载状态
我在使用Next.js 14结合Apollo实验库,搭配Suspense与useSuspenseQuery开发时遇到问题:刷新页面时,即便查询已在服务端执行完成,浏览器端仍会重复发起相同查询,导致每次刷新都要显示Suspense的加载状态。
Apollo Client配置已严格按照官方文档完成。
主RSC组件
import Paragraph from "@/ui/Paragraph"; import Breadcrumb from "@/components/breadcrumb"; import Heading from "@/ui/Heading"; import CategoriesLinkWithScroll from "@/ui/categorieslinkwithscroll"; import CategoryLink from "@/ui/categorylink"; import ErrorBoundary from "@/components/errorboundary"; import { Suspense } from "react"; import CategoryCards from "@/components/bingocardcategorypage/categorycards"; export default function CardCategoryPage({ pageData, ageGroups, cardDifficulties, }) { const title = pageData?.name; const description = pageData?.description; const breadcrumbs = pageData?.seo?.breadcrumbs; const breadcrumbTitle = pageData?.seo?.breadcrumbTitle; const childrenCategories = pageData?.children?.nodes; const databaseId = pageData?.databaseId; return ( <> <section className="py-4 lg:py-6"> <div className="container"> <div className="mb-3 lg:mb-6"> <Breadcrumb breadcrumbs={breadcrumbs} breadcrumbTitle={breadcrumbTitle} /> </div> <Heading level="h1" className="h1 font-recoleta mb-4"> {title} </Heading> <Paragraph className="sub-title sm:max-w-600px"> {description} </Paragraph> <CategoriesLinkWithScroll className="mt-4 md:mt-6"> {childrenCategories?.length > 0 && childrenCategories.map((category, index) => ( <CategoryLink key={`cloud_${index}`} label={category?.name} uri={category?.uri} /> ))} </CategoriesLinkWithScroll> </div> </section> <ErrorBoundary> <Suspense fallback={<div>....loading</div>}> <CategoryCards termId={databaseId} ageGroups={ageGroups} cardDifficulties={cardDifficulties} /> </Suspense> </ErrorBoundary> </> ); }
Cards组件
"use client"; import CategoryFilter from "@/components/categoryfilter"; import BlogReletedPostCard from "@/components/blogreletedpostcard"; import { useSuspenseQuery } from "@apollo/experimental-nextjs-app-support/ssr"; import GET_TEMPLATEBY_CATEGORY from "@lib/queries/wordpress/GET_TEMPLATEBY_CATEGORY"; import { useSearchParams } from "next/navigation"; import { siteUrls } from "@/utils/constant"; const gridSizesOptions = [ { value: "3", label: "3" }, { value: "4", label: "4" }, { value: "5", label: "5" }, { value: "9", label: "9" }, ]; export default function CategoryCards({ termId, ageGroups, cardDifficulties }) { const searchParams = useSearchParams(); const perPage = 12; const agegroup = searchParams.get("agegroup"); const gridsize = searchParams.get("gridsize"); const difficulty = searchParams.get("difficulty"); const variables = { first: perPage, cardCategories: `${termId}`, }; if (agegroup) { variables.ageGroups = agegroup; } if (gridsize) { variables.cardGrid = gridsize; } if (difficulty) { variables.cardDifficulty = difficulty; } const { data } = useSuspenseQuery(GET_TEMPLATEBY_CATEGORY, { variables: variables, fetchPolicy: "cache-first", }); const ageGroupOptions = ageGroups ? ageGroups?.nodes.map((ageGroup) => { return { label: ageGroup.name, value: ageGroup.databaseId }; }) : []; const cardDifficultiesOptions = cardDifficulties ? cardDifficulties?.nodes.map((cardDifficulty) => { return { label: cardDifficulty.name, value: cardDifficulty.databaseId, }; }) : []; const Cards = data?.bingoCards?.edges ? data.Cards.edges.map((edge) => edge.node) : []; return ( <section className="pt-4 pb-7 lg:pt-6 lg:pb-60px"> <div className="container"> <div className="flex justify-between items-center"> <div className="hidden gap-4 lg:flex"> <CategoryFilter options={ageGroupOptions} labelText="Age Group" name="agegroup" /> <CategoryFilter options={cardDifficultiesOptions} labelText="Difficulty" name="difficulty" /> <CategoryFilter options={gridSizesOptions} labelText="Grid Sizes" name="gridsize" /> </div> <button type="button" onClick={() => setOpenfilter(true)} className="flex items-center justify-center order-2 w-8 h-8 rounded-lg border border-solid border-gray-200 p-1.5 text-gray-600 lg:hidden" > <i className="bcc-filter" /> </button> <span className="text-xs font-medium text-primary-800 rounded bg-primary-50 py-1 px-2 lg:text-sm"> 56 cards </span> </div> <ul className="grid gap-8 grid-cols-1 py-6 not-prose lg:grid-cols-4"> {Cards.map((card, index) => { const cardImage = card?.cardImage ? JSON.parse(card.cardImage) : undefined; const imageUrl = cardImage ? siteUrls.cardImage(card?.cardId, cardImage?.value) : ""; return ( <BlogReletedPostCard key={card?.databaseId || index} tag="li" cardUrl={card?.uri} cardImageSrc={imageUrl} cardImageAltText={card?.title} cardImageWidth="284" cardImageHeight="284" cardTitle={card?.title} ageGroup={card?.ageGroups?.nodes} cardDificulties={card?.cardDifficulties?.nodes} isShownBadge={true} /> ); })} </ul> <button className="btn btn-primary w-full mx-auto px-5 mt-0 lg:mt-6 lg:w-auto"> Load more </button> </div> </section> ); }
内容的提问来源于stack exchange,提问作者vipul
相关产品推荐
相关产品推荐

