发布于 2026-01-05 3 阅读
0

Next.js(服务器端)中获取数据的不同方法以及何时使用它们

Next.js(服务器端)中获取数据的不同方法以及何时使用它们

使用 Next.js 构建应用程序时,您很可能需要从文件、内部 API 路由或外部 API (例如 Dev.to API)获取数据。此外,在 Next.js 应用程序中确定使用哪种数据获取方法很容易让人感到困惑——尤其是在它不像在标准的 React 应用程序中那样,可以在组件的渲染函数中直接发出 API 请求。

以下指南将帮助您仔细选择适合您应用程序的服务器端数据获取方法(请注意,您可以在单个应用程序中使用多种方法)。对于每种方法,我都概述了它的运行时机、优势以及在 Next.js 应用程序中使用该方法的示例。

以下方法可以在构建时或在每次请求时(在将数据发送到客户端之前)获取数据。

getStaticProps(静态生成)

在构建时获取数据

getStaticProps方法可用于页面内部,在构建时获取数据,例如在运行构建命令时next build。应用构建完成后,数据不会刷新,直到再次运行构建命令为止。

注:新增于 Next 9.3 版本

用法:

export async function getStaticProps(context) {
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  if (!data) {
    return {
      notFound: true,
    }
  }

  return {
    props: {}, // will be passed to the page component as props
  }
}
Enter fullscreen mode Exit fullscreen mode

好处:

  • 它使页面能够静态生成,从而加快所有数据获取方法的加载速度。
  • 如果你的应用中的每个页面都使用getStaticProps(或不使用)服务器端数据获取方法,那么 Next.js 就可以使用 `<script>` 标签将其导出为静态 HTML 。如果你想创建一个可以托管在GitHub Pages 等next export平台上的静态网站,这将非常有利
  • 数据在到达客户端之前就已渲染完毕——这对搜索引擎优化非常有利。

用法示例:

想象一下,你有一个个人博客网站,它在构建时根据 Markdown 文件渲染页面。VercelgetStaticProps可以读取这些文件,并在构建时将数据传递给页面组件。当你修改博客文章时,你需要重新构建网站才能看到更改。我创建的网站ameira.me就使用了这种方法——每次 Ameira 修改她的作品集时,Vercel 都会自动重新构建并发布网站。

getServerSideProps(服务器端渲染)

每次请求都获取数据

getServerSideProps方法会在用户每次请求页面时获取数据。它会在将页面发送给客户端之前获取数据(而不是在客户端加载页面并获取数据)。如果客户端发出后续请求,则会再次获取数据。

注:新增于 Next 9.3 版本

用法:

export async function getServerSideProps(context) {
  const res = await fetch(`https://...`)
  const data = await res.json()

  if (!data) {
    return {
      notFound: true,
    }
  }

  return {
    props: {}, // will be passed to the page component as props
  }
}
Enter fullscreen mode Exit fullscreen mode

好处:

  • 每次客户端加载页面时,数据都会刷新,这意味着数据在客户端访问页面时是最新的。
  • 数据在到达客户端之前就已渲染完毕——这对搜索引擎优化非常有利。

用法示例:

getServerSideProps它非常适合构建需要客户端查看最新信息,但页面内容在客户端停留期间不会刷新的应用程序(如需持续更新信息,请参阅客户端)。例如,如果我的个人网站上有一个页面显示我最近一次的 GitHub 提交或我当前的 Dev.to 统计数据,我希望每次页面被访问时都能获取这些信息。

getInitialProps(服务器端渲染)

每次请求都获取数据

getInitialProps这是在 Next.js 应用中从服务器端获取数据的原始方法。从 Next.js 9.3 开始,你应该使用前面讨论过的方法,getInitialProps但我在这里仍然保留它,因为:

  1. 它仍然可以使用——尽管 Next.js 维护者建议不要这样做,getStaticProps并且getServerSideProps允许您选择静态数据或服务器端数据获取。
  2. 了解这一点getInitialProps很有帮助,当你遇到一个提到它的旧 Stack Overflow 查询时,你就能找到答案,而且你也不应该直接复制粘贴那个解决方案!

注意:如果您使用的是 Next.js 9.3 或更高版本,请使用上述两种方法。

用法:

function Page({ stars }) {
  return <div>Next stars: {stars}</div>
}

Page.getInitialProps = async (ctx) => {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const json = await res.json()
  return { stars: json.stargazers_count }
}

export default Page
Enter fullscreen mode Exit fullscreen mode

好处:

同上getServerSideProps- 使用getServerSideProps

用法示例:

同上getServerSideProps- 使用getServerSideProps

如何决定使用哪一个?

在使用 Next.js 时,我总是力求使每个页面保持静态。这意味着我尽量避免使用 `div` getServerSideProps,而倾向于使用 `div` getStaticProps。但是,如果我获取的数据经常变化,那么我当然会使用 `div` getServerSideProps。我不再使用 `div`getInitialProps了。

所以通常我会尝试getStaticProps,如果这样导致数据过时,那么我会转移到其他方法getServerSideProps

关于客户端数据获取的一点说明

本文尚未介绍任何客户端数据获取方法,但您可以使用useEffecthook 发出请求,或者useSwr使用 Vercel 工程师实现的自定义 hook stale-while-revalidate

SWR 是一种策略,它首先从缓存中返回数据(过时的),然后发送获取请求(重新验证),最后返回最新数据。

- swr.vercel.app

驻波比用法:

import useSWR from 'swr'

function Profile() {
  const { data, error } = useSWR('/api/user', fetcher)

  if (error) return <div>failed to load</div>
  if (!data) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}
Enter fullscreen mode Exit fullscreen mode

结语

在本文中,我介绍了三种 Next.js 方法,它们可以在构建时或每次客户端请求之前获取数据。

喜欢这篇文章吗?那就点个赞吧!

感谢阅读!

文章来源:https://dev.to/jameswallis/ Different-ways-to-fetch-data-in-next-js-server-side-and-when-to-use-them-1jb0