既然动态页面是“服务器按需渲染”,为什么 nextjs 在构建期间执行其请求,即使在请求页面时会再次执行这些请求?
当我构建应用程序时,我可以看到 getData 函数运行两次,并执行网络请求来获取数据(我可以在 Mockoon 日志中看到 2 个传入请求)。
我希望在构建过程中只会发生对静态和 SSG 页面的请求,以便提前准备好页面。
○ (Static) prerendered as static content
● (SSG) prerendered as static HTML (uses getStaticProps)
ƒ (Dynamic) server-rendered on demand
我可以想象,如果我想缓存 getData 响应(通过使用 fetch),那么在构建时发出请求是有意义的,这样当某些用户请求页面时,可以从缓存中检索数据,但就我而言,我不想这样。
src/app/dynamictest/page.tsx
import { cookies } from "next/headers";
import Link from "next/link";
import { getDataWithAxios } from "../utils/callHelper";
type MockoonResponse = {
date: string;
seo: {
title: string;
description: string;
};
};
async function getData() {
try {
// No caching is being used
const res = await getDataWithAxios<MockoonResponse>({
method: "get",
params: {
whatever: "123",
},
endpoint: "http://127.0.0.1:4003/api/mockoontest",
});
return res;
} catch (error) {
console.error(error);
}
}
export async function generateMetadata() {
const res = await getData();
return {
title: res?.seo.title,
description: res?.seo.description,
};
}
export default async function Page() {
const isLoggedIn = cookies().get("access-token");
if (isLoggedIn) {
return <h2>Just to use cookies in code</h2>;
}
const data = await getData();
return (
<div>
<Link href="/">home</Link>
<h3>I am a dynamic page {data?.date}</h3>
</div>
);
}
问题:
为什么动态页面在构建期间执行请求(应用程序路由器)?
可能的原因:
export const dynamic = 'force-dynamic'
可能的解决方案:
将此行添加到dynamictest/page.tsx的顶部
export const dynamic = 'force-dynamic'
这将使该页面动态化,并防止其变为静态。
getData 函数运行两次 :
这可以通过使用react
cache
功能来防止
根据需要对代码进行必要的更改并处理错误。
export const dynamic = 'force-dynamic'
import { cache } from 'react'
const getData = cache(async () => {
try
{
const res = await getDataWithAxios<MockoonResponse>({
method: "get",
params: {
whatever: "123",
},
endpoint: "http://127.0.0.1:4003/api/mockoontest",
});
return res;
}
catch (error)
{
console.error(error);
return error
}
})
export async function generateMetadata(){
... // as it is
}
export default async function Page() {
... // as it is
}
请阅读:
如果您有任何疑问,请发表评论(如果有必要我会更新答案)