我正在为 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
不是未定义的。但是数据未定义。
我在这个问题上苦苦挣扎了几个小时,需要一些指导。
从这篇文章,我想知道:
在使用 SSR 时,使用 Next.js 中的
Link
不是正确的行为吗?通过使用Link
,我听说第一页的渲染是SSR条件,但CSR后记。
我想知道为什么
useQuery
不取数据,连id
都准备好参数了
第一个问题的答案:
SSR 中的链接组件总是调用
getServerSideProps
函数,这是无法避免的。 (使用浅路由时不会调用)。
一个技巧是检查对
getServerSideProps
的请求是否来自客户端导航,如果是,则返回一个空对象用于道具并处理客户端上的数据获取。
你的第二个问题:
我不确定发生了什么以及为什么您的
useQuery
挂钩无法获取数据,但是您的 getServerSideProps
中的水合物/脱水逻辑对我来说很奇怪,我没有找到任何水合物组件。
也许这就是导致您出现问题的原因。
我写了一篇关于使用 react-query 和 next.js SSR 的博文,希望对您有所帮助。