在 Next.js 中使用链接组件重新输入相同的 url 时,prefetchQuery 不获取数据(SSR)

问题描述 投票:0回答:1

我正在为 SSR 使用 Next.js 和 React Query。

一切正常,直到重新进入确切的动态路线(例如

domain/support/guide/faq/[id]
)。

预期的行为是在不获取数据的情况下呈现查询数据,因为我对组件使用了 SSR。

请检查我的代码

// PAGE, I pass the query string to the <FAQContent /> Component

export default function FAQDetailPage({ id }: { id: string }) {

  return <FAQContent id={id} category={"faq"} />;
}

export async function getServerSideProps({
  query: { id },
}: {
  query: { id: string };
}) {
  const queryClient = new QueryClient();

  try {
    await queryClient.prefetchQuery(["support", "faq", id], () => {
      return sendRequest({
        method: "get",
        path: `/article/${id}`,
        apiType: "Contents",
      });
    });
  } catch (e) {
    return {
      redirect: {
        destination: "/",
        permanent: false,
      },
    };
  }

  const dehydratedQueryClient = dehydrate(queryClient);

  const targetQuery = dehydratedQueryClient.queries[0];

  const targetQueryState = targetQuery.state as any;

  return {
    props: {
      dehydratedState: {
        ...dehydratedQueryClient,
        queries: [
          {
            ...dehydrate(queryClient).queries[0],
            state: {
              ...targetQueryState,
              data: targetQueryState.data.data,
            },
          },
        ],
      },
      id,
    },
  };
}

// Get id and category from the page, and pass to <SupportBoardContent />

export default function FAQContent({
  id,
  category,
}: {
  id: string;
  category: string;
}) {

  return <SupportBoardContent id={id} category={category} />;
}
// Here is the component where hydrate the dehydrated query

export default function SupportBoardContent({
  id,
  category,
}: {
  id: string;
  category: string;
}) {
  const router = useRouter();

  const { pathname } = router;

  // This is a hook for useQuery.
  const {
    data: boardContent,
    ResponseHandler: ResponseHandlerOfGetBoardContent,
  } = SUPPORT_QUERY.useGetBoardContent({
    id,
    category,
  });

  const { title, contents, memo, videoURL, articleType } =
    boardContent?.targetArticle || {};


  return (
    <SupportLayout>

      {boardContent && (
        <CommonStyled.mainContainer>
          <SupportBreadcrumb title={title} />
          <BoardPageTitle titleStyle="default">
            {getArticleBoardTypeString(articleType)}
          </BoardPageTitle>
          <BoardContent
            title={title}
            annotation={memo}
            desc={contents}
            videoURL={videoURL}
          />
        </CommonStyled.mainContainer>
      )}
    </SupportLayout>
  );
}

当组件第一次安装时,没有错。一切如我所料。但是,有一个

<SupportBreadCrumb />
组件。

<SupportBreadCrumb />
中,我使用
Link
来自
Next/link
。每当我尝试使用
Link
组件进入同一页面时,
data
中的
useQueryHook
是未定义的。

id
不是未定义的,
category
不是未定义的。但是数据未定义。

我在这个问题上苦苦挣扎了几个小时,需要一些指导。

从这篇文章,我想知道:

  1. 在使用 SSR 时,使用 Next.js 中的

    Link
    不是正确的行为吗?通过使用
    Link
    ,我听说第一页的渲染是SSR条件,但CSR后记。

  2. 我想知道为什么

    useQuery
    不取数据,连
    id
    都准备好参数了

reactjs next.js server-side-rendering client-side react-query
1个回答
0
投票

第一个问题的答案:
SSR 中的链接组件总是调用

getServerSideProps
函数,这是无法避免的。 (使用浅路由时不会调用)。

一个技巧是检查对

getServerSideProps
的请求是否来自客户端导航,如果是,则返回一个空对象用于道具并处理客户端上的数据获取。

你的第二个问题:
我不确定发生了什么以及为什么您的

useQuery
挂钩无法获取数据,但是您的
getServerSideProps
中的水合物/脱水逻辑对我来说很奇怪,我没有找到任何水合物组件。 也许这就是导致您出现问题的原因。

我写了一篇关于使用 react-query 和 next.js SSR 的博文,希望对您有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.