Next.js getStaticProps

118 阅读3分钟

getStaticProps 是 Next.js 提供的用于 静态生成页面 的 API。与 getServerSideProps 不同,getStaticProps 在构建时(build time)执行,并生成静态页面。这意味着当你部署应用后,页面不需要每次请求时都重新生成,而是从预生成的静态页面中直接读取内容。

静态生成适用于那些数据在构建时就已确定的页面,比如博客文章、产品页面等。相比动态渲染,它在性能和页面加载速度上有很大的优势。

使用场景
  1. 数据在构建时可以获取,并且不需要频繁更新。
  2. 想要提升页面的加载速度,并且减少服务器的压力。
  3. SEO 要求较高,页面内容在构建时生成,便于搜索引擎抓取。
示例:静态生成博客文章页面

我们用一个简单的例子,展示如何使用 getStaticProps 来静态生成博客文章页面。

1. 创建页面组件

首先在 pages/posts/[id].js 文件中创建一个博客文章页面。

// pages/posts/[id].js

export default function Post({ post }) {
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
    </div>
  );
}

// 使用 getStaticProps 来获取静态数据
export async function getStaticProps({ params }) {
  // 根据文章 ID 获取文章数据
  const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${params.id}`);
  const post = await res.json();

  return {
    props: {
      post,
    },
  };
}

// 使用 getStaticPaths 来指定静态生成哪些路径
export async function getStaticPaths() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts');
  const posts = await res.json();

  // 为每篇文章生成路径
  const paths = posts.map(post => ({
    params: { id: post.id.toString() },
  }));

  return { paths, fallback: false };
}
2. 代码解析
  • getStaticProps

    • 这个函数在构建时运行,并获取静态数据。在这个例子中,它从外部 API 中获取单篇博客文章的数据。
    • 通过 return { props: { post } } 将获取到的 post 数据传递给页面组件,页面会在构建时生成静态 HTML。
  • getStaticPaths

    • getStaticPaths 用于告诉 Next.js 应该静态生成哪些路径。在这个例子中,我们从 API 获取所有文章的列表,并为每篇文章生成一个路径(如 /posts/1/posts/2)。
    • paths 数组中的每个对象表示一个需要静态生成的页面路径,params.id 对应 URL 中的动态路由参数。
    • fallback: false 意味着除了指定的路径之外,其他路径都会返回 404。
3. 运行效果

构建应用时,Next.js 会根据 getStaticPaths 返回的路径生成静态 HTML 页面。生成完成后,当用户访问 /posts/1 时,Next.js 不会再进行服务器端渲染,而是直接从静态文件中返回页面。

页面将显示如下内容:

Post Title
Post Body Content

这个过程大大加快了页面加载速度,因为页面在构建时已经准备好,不需要每次请求都重新获取数据和渲染。

如何优化 getStaticProps
  1. 增量静态生成 (ISR):如果页面内容需要定期更新但不需要实时更新,可以结合 getStaticPropsrevalidate 属性来设定一个重新生成页面的时间间隔。例如:
export async function getStaticProps() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts/1');
  const post = await res.json();

  return {
    props: {
      post,
    },
    revalidate: 60, // 每隔60秒重新生成页面
  };
}

这样,Next.js 会在第一次请求时返回已生成的静态页面,并在后台自动更新页面内容,每隔 60 秒生成一次新的静态页面。

  1. 优先静态生成热门页面:对于流量较大的页面,可以手动选择预生成这些页面,而让其他页面使用动态渲染或增量生成。这种方法既能确保热门页面的高性能,又能保证动态内容的灵活性。
使用 getStaticProps 的限制
  • getStaticProps 只能在页面组件中使用,不能在普通组件或 API Routes 中使用。
  • getStaticProps 只能获取静态数据,不能处理像用户认证这样的动态信息。如果需要根据用户信息渲染页面,可以结合 getServerSideProps