为什么动态页面在构建(应用程序路由器)期间执行请求?

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

既然动态页面是“服务器按需渲染”,为什么 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>
  );
}
next.js app-router nextjs-dynamic-routing
1个回答
0
投票

问题:

为什么动态页面在构建期间执行请求(应用程序路由器)?

可能的原因:

  • 页面不是动态的,因为您还没有使用过
    export const dynamic = 'force-dynamic'
  • 也因为这个页面不是动态路由。 /user/[id] 这里的 id 是动态的,这使得页面自动动态化。
  • 但是,由于非动态文件夹中只有一个 page.tsx,nextjs 会将其设置为静态的、服务器端渲染的,因为它的默认行为。

可能的解决方案:

  • 将此行添加到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
}

请阅读:

如果您有任何疑问,请发表评论(如果有必要我会更新答案)

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