首页
/ Next.js 数据获取指南:深入理解 getStaticProps

Next.js 数据获取指南:深入理解 getStaticProps

2025-07-05 01:46:44作者:仰钰奇

什么是 getStaticProps?

在 Next.js 项目中,getStaticProps 是一个强大的数据获取方法,用于在构建时预渲染页面。它属于静态站点生成(SSG)策略的一部分,允许开发者在页面组件之外获取数据,并将这些数据作为 props 传递给页面组件。

核心特性解析

1. 工作原理

当你在页面文件中导出一个名为 getStaticProps 的函数时,Next.js 会在构建时执行这个函数:

  1. 在构建阶段调用 getStaticProps
  2. 获取函数返回的数据
  3. 使用这些数据预生成静态 HTML 页面
  4. 同时生成包含这些数据的 JSON 文件

2. 基本用法示例

import type { GetStaticProps } from 'next'

interface Post {
  id: number
  title: string
  content: string
}

export const getStaticProps: GetStaticProps<{ posts: Post[] }> = async () => {
  // 这里可以访问数据库或API
  const res = await fetch('https://api.example.com/posts')
  const posts: Post[] = await res.json()
  
  return {
    props: {
      posts,
    },
    // 启用增量静态再生(ISR),每10秒重新验证一次
    revalidate: 10,
  }
}

function BlogPage({ posts }: { posts: Post[] }) {
  return (
    <div>
      {posts.map(post => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.content}</p>
        </article>
      ))}
    </div>
  )
}

export default BlogPage

适用场景分析

getStaticProps 最适合以下情况:

  1. 构建时可获取的数据:页面内容在构建时就能确定,不需要每次请求时获取
  2. 无用户个性化数据:页面内容对所有用户相同
  3. 需要极快加载速度:生成的静态文件可以被CDN缓存
  4. SEO关键页面:预渲染的HTML对搜索引擎友好
  5. 内容管理系统(CMS)数据:从无头CMS获取内容

高级用法技巧

1. 类型安全(TypeScript)

使用 TypeScript 可以增强类型安全:

import type { InferGetStaticPropsType } from 'next'

export async function getStaticProps() {
  const res = await fetch('https://api.example.com/data')
  const data = await res.json()
  
  return {
    props: {
      data
    }
  }
}

type DataType = {
  id: number
  name: string
}

export default function Page({
  data
}: InferGetStaticPropsType<typeof getStaticProps>) {
  // data 现在有正确的类型推断
  return <div>{data.name}</div>
}

2. 增量静态再生(ISR)

通过 revalidate 属性实现增量静态再生:

export async function getStaticProps() {
  const res = await fetch('https://api.example.com/latest-data')
  const data = await res.json()
  
  return {
    props: { data },
    // 每60秒重新生成页面
    revalidate: 60,
  }
}

3. 直接访问数据库

由于 getStaticProps 只在服务端运行,可以直接访问数据库:

import { connectToDatabase } from '../lib/mongodb'

export async function getStaticProps() {
  const { db } = await connectToDatabase()
  const posts = await db.collection('posts').find({}).toArray()
  
  return {
    props: {
      posts: JSON.parse(JSON.stringify(posts))
    }
  }
}

注意事项

  1. 客户端不可见getStaticProps 代码不会出现在客户端bundle中
  2. 仅限页面文件:只能在 pages 目录下的文件中使用
  3. 开发模式行为:在开发模式下(next dev),每次请求都会调用
  4. 无请求对象访问:无法访问HTTP请求头或查询参数
  5. 数据大小限制:传递的数据会被序列化为JSON,注意大小限制

性能优化建议

  1. 减少数据量:只获取页面需要的最小数据集
  2. 使用缓存:对API响应进行适当缓存
  3. 代码分割:将数据获取逻辑移到共享的 lib 目录
  4. 并行请求:使用 Promise.all 并行获取多个数据源
  5. 错误处理:添加适当的错误处理逻辑

常见问题解答

Q: getStaticPropsgetServerSideProps 有什么区别?

A: 主要区别在于执行时机:

  • getStaticProps 在构建时运行,生成静态页面
  • getServerSideProps 在每个请求时运行,生成动态内容

Q: 可以在 getStaticProps 中使用环境变量吗?

A: 可以,使用 process.env 访问环境变量,但要注意这些变量在构建时就已经确定。

Q: 如何处理动态路由与 getStaticProps 的结合?

A: 需要配合 getStaticPaths 使用,为每个动态路由生成静态页面。

通过深入理解和合理应用 getStaticProps,你可以构建出既快速又功能丰富的 Next.js 应用,同时保持良好的开发体验和优秀的终端用户性能。