#04 No-code 之旅 — Next.js 中的 Pre-render 与 Data Fetching

嗨大家!昨天跟大家分享了四种网页渲染方式,那今天来讲讲该怎麽用 Next.js 实作~ 在 Next.js 里,抓取资料的方式会影响到渲染方式。上一篇提到 Next.js 提供的三个 functions 就是用来抓取资料做预渲染 (产生包含内容资料的 HTML 档案) 的,我们一起看下去~

注意:想要用这三个 functions 的话,一定要在 Next.js 的 page (页面) 档案里面做 export 喔。

注意:这三个 functions 会在 server (服务器) 端跑完,因此我们可以在里面写後端程序码,甚至操作资料库。

Next.js Pre-rendering

getStaticProps (Static Generation)

这 function 会在 build time 的时候跑而抓取所需要的资料,就是当我们执行 npm run build 的时候跑的。这 function 可以回传 props object (物件) 当该 page 的 props,这 page 需要的资料就透过 props 传进去的。服务器跑完这 function 之後,除了产生了 HTML 档案之外,还会产生了 JSON 档案。为什麽呢?因为在 client-side (客户端) 切换页面的时候,浏览器会读这 JSON 档案里面的资料用来显示 page 内容。

// 在 build time 的时候跑在服务器端
export async function getStaticProps() {
  // 可以直接抓取资料或是操作资料库
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    // 传给该 page 的 props
    props: {
      posts,
    },
    // 过了 10 秒之後,可以重新验证/重新产生
    revalidate: 10,
  }
}

getStaticProps 接收 context 当 parameter,而 context 包含渲染该 page 的相关资讯,可以在这里看官方的 docsgetStaticProps 回传一个物件而里面包含:

  • props (optional):传给 page 当该 page 的 props
  • revalidate (optional):实作 ISR 用的,如果设定 false 代表只会 build 一次,就是整个专案跑 npm run build 的时候。如果设定秒数,代表过几秒之後可以重新 generate (产生) 这 page 做 revalidation (重新验证) 更新 page 的资料。不过服务器会先回传 cache 里的旧 page 给浏览器然後在背後 revalidate 完才回传最新的 page 给浏览器,让浏览器去做更新
  • notFound (optional):找不到资料的时候,决定是否回传 404 的 status code 与 error page
  • redirect (optional):设定是否要导页而且导去哪里,用物件的形式 { destination: string, permanent: boolean } 或是 { destination: string, statusCode: number }

与 SSG 或 ISR 的关系

getStaticProps 会在 build time 的时候跑在服务器端,把抓取到的资料塞进该 page 对应到的 HTML 档案,让 HTML 档案包含了资料内容,而可以直接丢给浏览器去显示,这就是 SSG。如果设定了 revalidation秒数,该 page 会进行重新验证/重新产生的过程,这是 ISR。

不过,如果在 dynamic (动态) routes 的 page 里有用到 getStaticProps,那需要搭配 getStaticPaths 才能正确运作,可以去下一段看看为什麽~

关於 dynamic routes 会在之後解释喔。

getStaticProps

getStaticPaths (Static Generation)

一样会在服务器端 build time 的时候跑的,名字跟上一个 function 也有点像,虽然用途不一样,可是这两个 function 常常用在一起。这 function 抓取资料的目的并不是变成网页的内容,而是用这些资料决定需要产生哪些 dynamic (动态) routes 的 HTML 档案。

export async function getStaticPaths() {
  return {
    paths: [
      { params: { id: '1' } },
      { params: { id: '2' } }
    ],
    fallback: true, false, or 'blocking'
  };
}

getStaticPaths 回传一个物件而里面包含:

  • paths (required):决定要产生哪些 paths 的 HTML 档案,每个 path 是一个物件包含 params 物件。如果你的 path 是 posts/[id]id 是动态的,那 params 里面要定义 id 的值。所以上面那段 code 只会去产生两个 HTML 档案,pages/posts/1.htmlpages/posts/2.html
  • fallback (required):决定找不到 page 的时候的行为,总共有三种方法
    • true:当 page 不在 paths 里面,服务器会回传一个备份版本的 page,而该 page 可能是空的或是 loading 状态 (由我们决定),然後服务器在背後去产生该 page 的 JSON 档案,等到完成之後再传给浏览器去做显示,也会把这新产生的 page 放在 CDN 的 cache 里
    • false:如果该 page 不在 paths 里面,而找不到该 page 的 HTML 档案,会拿到 404 error code 而显示 404 error page
    • 'blocking':当 page 不在 paths 里面,服务器会产生该 page 的 HTML 档案而这段期间浏览器是等待的状态 (白画面),等到 HTML 档案产生完才回传给浏览器做显示。这一次服务器是采用 SSR 的方式,不过产生完之後,HTML 档案一样会被放到 CDN 的 cache 里

与 SSG 或 ISR 的关系

getStaticPaths 会在 build time 的时候跑在服务器端,把抓取到的资料决定该产生 dynamic routes 的哪些 paths。这些 paths 再往里面跑每个 page 的 getStaticProps 产生 HTML 和 JSON 档案。没有 getStaticPaths 就不会有 dynamic routes 相关的 page 了!

getStaticPaths

getServerSideProps (Server-side Rendering)

最後一个!这 function 很像 getStaticProps,回传的值差不多,一样在服务器端跑。不一样的点是它不是 build 的时候跑的,而是每次有 request (请求) 的时候才会跑。跟 getStaticProps 也一样除了会产生 HTML 档案之外,还会产生了 JSON 档案。

export async function getServerSideProps(context) {
  return {
    props: {}, // 传给该 page 的 props
  }
}

getServerSideProps 接收 context 当 parameter,而 context 包含渲染该 page 的相关资讯,可以在这里看官方的 docsgetServerSideProps 回传一个物件而里面包含:

  • props (optional):传给 page 当该 page 的 props
  • notFound (optional):找不到资料的时候,决定是否回传 404 的 status code 与 error page
  • redirect (optional):设定是否要导页而且导去哪里,用物件的形式 { destination: string, permanent: boolean } 或是 { destination: string, statusCode: number }

与 SSR 的关系

getServerSideProps 会在每一次的 request time 的时候跑在服务器端,把抓取到的资料塞进该 page 对应到的 HTML 档案,让 HTML 档案包含了资料内容,而可以直接丢给浏览器去显示,这就是 SSR。产生档案的过程中,浏览器会显示白画面,所以使用者可能会觉得显示很慢,而且 SSR 产生的 HTML 档案不会自动被 CDN 做 cache (需要特别设定喔~)。

getServerSideProps

Client-side 抓取资料

以上三个 function 都是跑在服务器端抓取资料,可是如果需要一直更新资料或是不需要 SEO,那其实可以采用 CSR,在 client-side (客户端) 去抓取资料~ 这部分跟一般在写 React 需要拿资料的时候一模一样,可能就是在 useEffect 去抓取资料然後画面显示 loading 状态!

小结

今天讲的好像有点多XD
明天跟大家分享 Next.js 中的 pages 与 routing!也就是会讲到 dynamic routes 的部分喔 :)
祝大家中秋节快乐!

晚安 <3

看更多


<<:  Day 17 | 常用范例:前後端共用的表单输入验证 Validate

>>:  [day7] API回覆内容(Response)解析 & 验证(sign)

【15】图片标准化 [0,1] 与 [-1,+1] 的差别实验

Colab连结 昨天我们实验了有无做 Normalization 的差异,但我在 stackover...

Day 16 | 元件状态:预载 及 延迟载入 Prefetch & Defer Loading

今天因为这两个功能都比较简单,因此合在一起讲。分别是 预载(Prefetching) 与 延迟载入(...

Day 11 阿里云架设网站-DNS & 智能流量分流

云解析(Alibaba Cloud DNS) 云解析是一个在阿里上的DNS托管工具,每个云端都有他自...

< 关於 React: 开始打地基| JSX >

09-03-2021 前情提要 以往的学习经验来说,在撰写前端时一定会遇到的三大巨人:HTML,掌管...

[Day27] HTB Legacy

URL : https://app.hackthebox.eu/machines/2 IP : 1...