Next.js的预渲染

Next.js如何为我们预渲染页面

getStaticProps

通过在页面(pages)中添加导出的getStaticProps函数,我们可以告诉Next.js我们想要预渲染的页面。Next.js将在构建时(yarn build)
运行此函数,并将返回的数据序列化为JSON,以便在页面加载时可以使用。

此函数的返回值是固定的,必须是一个对象

export const getStaticProps: GetStaticProps = async () => {
  const post = (await fetch(`https://api/todos`)).json();

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

props

返回对象中包含props键,其值是要传递给页面的数据。页面可以通过添加props参数获取此数据。

const HomePage = (props: { post: object }) => {
  const { post } = props;
  return (
    <div>
      <h1>{ post.title }</h1>
      <p>{ post.body }</p>
    </div>
  );
}

revalidate

通过在返回值中添加revalidate: x(x是数字类型), 告诉Next.js,这个页面应该在被构建和部署之后,
每过x秒重新执行getStaticProps函数并生成页面

export const getStaticProps: GetStaticProps = async () => {
  const post = (await fetch(`https://api/todos`)).json();

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

notFound

通过在返回值中添加notFound: true, 告诉Next.js,如果没有数据,就返回404页面。

getStaticPaths

对于动态路由来说, 开发者必须让Next.js知道哪些路径是预渲染的。这是通过在页面中添加导出的getStaticPaths函数来完成的。
它的返回值是固定的,必须是一个对象, 包含paths键,其值是一个数组,数组中包含了预渲染的路径参数。

Next.js将在构建时运行getStaticPaths函数,并将返回的路径参数数组在getStaticProps函数中使用, 对于每一个页面创建它的实例。

例如,如果您的页面路径是pages/posts/[id].tsx,则可以通过以下方式导出getStaticPaths函数:

export const getStaticPaths: GetStaticPaths = async () => {
  const paths = [
    { params: { id: '1' } },
    { params: { id: '2' } },
    { params: { id: '3' } },
  ];

  return {
    paths,
    fallback: false,
  };
}

同时, 你还需要在pages/posts/[id].tsx中添加getStaticProps函数, 获取getStaticPaths函数返回的路径参数id数组。

export const getStaticProps: GetStaticProps = async (context) => {
  const { id } = context.params;
  const post = (await fetch(`https://api/todos/${ id }`)).json();

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

这个例子的结果是,Next.js会在构建时为每个id值生成一个页面实例, 如果getStaticProps中添加了revalidate,
那么Next.js会在x秒后重新运行getStaticPaths和getStaticProps函数,并生成每个页面实例。

fallback

getStaticPaths的返回值中的fallback属性是一个布尔值。

true

fallback: true表示,如果没有当前路由的页面实例,不会返回404页面,但是会在后台运行getStaticProps函数,直到有页面生成。

  1. 由getStaticPaths返回的路径参数数组会由getStaticProps在构建时生成每个页面实例。

  2. 用户在访问那些没有在构建时被预渲染的页面实例时,不会收到404页面。服务器会先返回一个“fallback
    ”版本(页面组件的props为空, router.isFallback = true)的页面.

  3. 在后台,Next.js 会静态生成请求的路径 HTML 和 JSON。这包括运行 getStaticProps。

  4. 完成后,浏览器会收到已被生成的路径的 JSON。这将用于自动呈现具有所需props的页面。从用户的角度来看,页面将从"fallback"
    页面切换到完整页面。

  5. 同时,Next.js 将此路径添加到预渲染页面列表中。对同一路径的后续请求将提供生成的页面,就像在构建时预呈现的其他页面一样。

如果您的应用程序有大量依赖于数据的静态页面(例如非常大的电子商务网站),则该选项很有用。如果你想预渲染所有产品页面,构建将花费很长时间。

相反,您可以静态生成一小部分页面并使用 fallback: true 来处理其余页面。当有人请求尚未生成的页面时,用户将看到带有加载指示器或骨架组件的页面。

不久之后,getStaticProps 完成,页面将使用请求的数据呈现。从现在开始,每个请求同一页面的人都将获得静态预渲染页面。

这可确保用户始终拥有快速体验,同时保留快速构建和静态生成的优势。

fallback: true 不会更新生成的页面. 如果你想要更新页面, 你需要重新构建.

相关概念查看Incremental Static Regeneration(ISR)

false

fallback: false表示,如果没有当前路由的页面实例,就返回404页面,不会在后台运行getStaticProps函数。
所以, fallback: false 比较适合用于较小的静态网站,只有等网站的管理者添加内容时,重新让Next.js构建后,才会生成新的页面。

blocking

如果fallback: blocking,则 getStaticPaths 未返回的新路径将等待生成 HTML,与 SSR 相同(因此阻塞),然后缓存以供将来请求使用,因此每个路径的页面只生成一次。

  1. 构建时未生成的路径不会产生 404 页面。相反,Next.js 将在第一次请求时进行 SSR 并返回生成的 HTML。
  2. 完成后,浏览器会收到生成路径的 HTML。从用户的角度来看,它将从“浏览器正在请求页面”过渡到“完整页面已加载”。没有加载/回退状态的闪烁。
  3. 同时,Next.js 将此路径添加到预渲染页面列表中。对同一路径的后续请求将提供生成的页面,就像在构建时预呈现的其他页面一样。
  4. 默认情况下,‘blocking’ 不会更新生成的页面。如果您希望更新页面,则需要重新构建。

getServersideProps

如果您从页面导出一个名为 getServerSideProps(服务器端渲染)的函数,Next.js 将使用 getServerSideProps 返回的数据在每个请求上预渲染该页面。

getServerSideProps 仅在服务器端运行,从不在浏览器上运行。如果页面使用 getServerSideProps

  1. 当您直接请求此页面时,getServerSideProps 在请求时运行,此页面将使用返回的 props 进行预渲染
  2. 当您通过 next/link 或 next/router 在客户端页面转换上请求此页面时,Next.js 会向服务器发送 API 请求,服务器运行
    getServerSideProps
  3. 当从页面导出一个名为 getServerSideProps(服务器端渲染)的函数时,Next.js 将使用 getServerSideProps
    返回的数据在每个请求上预渲染该页面。如果您想要获取经常更改的数据并让页面更新以显示最新数据,这将很有用。
  4. 您可以在顶级范围内导入模块以在 getServerSideProps 中使用。使用的导入不会为客户端捆绑。这意味着您可以直接在
    getServerSideProps 中编写服务器端代码,包括从数据库中获取数据。
export const getServerSideProps: GetServerSideProps = async (context) => {
  /*
   * params: 参数
   * req: http请求
   * res: http响应
   * */
  const { params, req, res } = context;
  return {
    props: {}, // will be passed to the page component as props
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值