getStaticProps
如果您从页面导出名为 getStaticProps
(静态站点生成)的函数,则 Next.js 将在构建时使用 getStaticProps
返回的 props 预渲染此页面。
import type { InferGetStaticPropsType, GetStaticProps } from 'next'
type Repo = {
name: string
stargazers_count: number
}
export const getStaticProps = (async (context) => {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
const repo = await res.json()
return { props: { repo } }
}) satisfies GetStaticProps<{
repo: Repo
}>
export default function Page({
repo,
}: InferGetStaticPropsType<typeof getStaticProps>) {
return repo.stargazers_count
}
请注意,无论渲染类型如何,任何
props
都将传递给页面组件,并且可以在客户端的初始 HTML 中查看。这是为了允许页面正确水合。确保您不要在props
中传递任何不应在客户端上可用的敏感信息。
有关 getStaticProps
的所有参数和 props,请参阅getStaticProps
API 参考。
何时应该使用 getStaticProps?
如果满足以下条件,则应使用 getStaticProps
:
- 渲染页面所需的数据在用户请求之前构建时可用
- 数据来自无头 CMS
- 页面必须预渲染(用于 SEO)并且速度非常快 -
getStaticProps
生成HTML
和JSON
文件,这两个文件都可以被 CDN 缓存以提高性能 - 数据可以公开缓存(非用户特定)。在某些特定情况下,可以通过使用中间件重写路径来绕过此条件。
getStaticProps 何时运行
getStaticProps
始终在服务器上运行,绝不在客户端上运行。您可以验证 getStaticProps
内部编写的代码是否已从客户端捆绑包中删除使用此工具。
getStaticProps
始终在next build
期间运行- 当使用
fallback: true
时,getStaticProps
在后台运行 - 当使用
fallback: blocking
时,getStaticProps
在初始渲染之前被调用 - 当使用
revalidate
时,getStaticProps
在后台运行 - 当使用
revalidate()
时,getStaticProps
在后台按需运行
与增量静态再生结合使用时,getStaticProps
将在后台运行,同时旧页面正在重新验证,并将新页面提供给浏览器。
getStaticProps
无法访问传入的请求(例如查询参数或 HTTP 标头),因为它生成静态 HTML。如果您需要访问页面请求,请考虑除了 getStaticProps
之外还使用中间件。
使用 getStaticProps 从 CMS 获取数据
以下示例演示了如何从 CMS 获取博客文章列表。
// posts will be populated at build time by getStaticProps()
export default function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
)
}
// This function gets called at build time on server-side.
// It won't be called on client-side, so you can even do
// direct database queries.
export async function getStaticProps() {
// Call an external API endpoint to get posts.
// You can use any data fetching library
const res = await fetch('https://.../posts')
const posts = await res.json()
// By returning { props: { posts } }, the Blog component
// will receive `posts` as a prop at build time
return {
props: {
posts,
},
}
}
有关 getStaticProps
的所有参数和 props,请参阅getStaticProps
API 参考。
直接编写服务器端代码
由于getStaticProps
仅在服务器端运行,因此它永远不会在客户端运行。它甚至不会包含在浏览器的 JS 包中,因此您可以编写直接的数据库查询,而无需将其发送到浏览器。
这意味着,您可以直接在getStaticProps
中编写服务器端代码,而不是从getStaticProps
获取API 路由(该路由本身从外部源获取数据)。
以以下示例为例。一个 API 路由用于从 CMS 获取一些数据。然后,该 API 路由直接从getStaticProps
中调用。这会导致额外的调用,从而降低性能。相反,可以通过使用lib/
目录来共享从 CMS 获取数据的逻辑。然后,它可以与getStaticProps
共享。
// The following function is shared
// with getStaticProps and API routes
// from a `lib/` directory
export async function loadPosts() {
// Call an external API endpoint to get posts
const res = await fetch('https://.../posts/')
const data = await res.json()
return data
}
// pages/blog.js
import { loadPosts } from '../lib/load-posts'
// This function runs only on the server side
export async function getStaticProps() {
// Instead of fetching your `/api` route you can call the same
// function directly in `getStaticProps`
const posts = await loadPosts()
// Props returned will be passed to the page component
return { props: { posts } }
}
或者,如果您**没有**使用 API 路由来获取数据,则可以在getStaticProps
中直接使用fetch()
API。
要验证 Next.js 从客户端包中删除的内容,您可以使用next-code-elimination 工具。
静态生成 HTML 和 JSON
当在构建时预渲染具有getStaticProps
的页面时,除了页面 HTML 文件之外,Next.js 还会生成一个 JSON 文件,其中包含运行getStaticProps
的结果。
此 JSON 文件将在客户端路由中通过next/link
或next/router
使用。当您导航到使用getStaticProps
预渲染的页面时,Next.js 会获取此 JSON 文件(在构建时预先计算)并将其用作页面组件的 props。这意味着客户端页面转换**不会**调用getStaticProps
,因为仅使用导出的 JSON。
在使用增量静态生成时,getStaticProps
将在后台执行,以生成客户端导航所需的 JSON。您可能会看到为同一页面发出多个请求,但这在预期之内,并且不会影响最终用户的性能。
在哪里可以使用 getStaticProps
getStaticProps
只能从页面导出。您**不能**从非页面文件、_app
、_document
或_error
中导出它。
此限制的原因之一是 React 需要在渲染页面之前拥有所有必需的数据。
此外,您必须将getStaticProps
作为独立函数导出——如果您将getStaticProps
作为页面组件的属性添加,它将**无法**工作。
注意:如果您创建了自定义应用,请确保您将
pageProps
传递给页面组件,如链接文档中所示,否则 props 将为空。
在每次请求中运行(开发环境)
在开发模式(next dev
)下,getStaticProps
将在每次请求时被调用。
预览模式
您可以使用预览模式暂时绕过静态生成,并在请求时而不是构建时渲染页面。例如,您可能正在使用无头 CMS,并且希望在发布之前预览草稿。
这有帮助吗?