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

When re-entering same url with Link Component in Next.js, prefetchQuery doesn't fetch data (SSR)

提问人:carryon 提问时间:2/28/2023 更新时间:3/2/2023 访问量:685

问:

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

在重新进入确切的动态路由(例如)之前,一切都很好。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 />

在 中,我使用 from .每当我尝试使用 Component 进入同一页面时,from 都是未定义的。<SupportBreadCrumb />LinkNext/linkLinkdatauseQueryHook

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

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

从这篇文章中,我想知道:

  1. 使用 SSR 时,使用 from Next.js 是否不是正确的行为?通过使用,我听说第一页的渲染是 SSR 条件,但做 CSR 后记。LinkLink

  2. 我想知道为什么不获取数据,甚至准备好参数。useQueryid

reactjs next.js 服务器端渲染客户端 react-query

评论


答:

0赞 Arian Hamdi 3/2/2023 #1

回答第一个问题:
SSR 中的链接组件总是调用该函数,这是无法阻止的。(使用浅层路由时,它不会调用)。
getServerSideProps

一个诀窍是检查请求是否来自客户端导航,如果是,则返回一个 props 的空对象,并在客户端上处理数据获取。getServerSideProps

你的第二个问题:
我不确定发生了什么以及为什么你的钩子无法获取数据,但你在你中的水合物/脱水物逻辑对我来说很奇怪,我没有找到任何水合物组件。 也许这就是导致你问题的原因。
useQuerygetServerSideProps

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